#c# #charts #distance #mschart #series
#c# #Диаграммы #расстояние #mschart #Серии
Вопрос:
У меня есть диаграмма с двумя рядами. Теперь я хочу найти максимальное расстояние между чатами вдоль оси x за заданный интервал. Для решения проблемы было бы достаточно вычисления расстояния по заданной точке x, как на рисунке, при x = 50.
У меня есть следующий код:
public void MaxSpacing(object chart, int series1, int series2)
{
Chart tmpChart = (Chart)chart;
double distance = 0;
int positon = 0;
for (int i = 0; i < tmpChart.Series[series1].Points.Count(); i )
{
if ((Math.Abs(tmpChart.Series[series1].Points[i].YValues[0] - tmpChart.Series[series2].Points[i].YValues[0])) > distance)
{
distance = tmpChart.Series[series1].Points[i].YValues[0] - tmpChart.Series[series2].Points[i].YValues[0];
}
}
Проблема этого кода в том, что он использует точки данных обоих рядов. Если количество / интервал точек в series1 и series2 отличается, вычисление не работает. Итак, я ищу значения Y для заданного значения X, чтобы вычислить расстояние.
Комментарии:
1. звучит как линейная интерполяция, просто соедините линии через точки. вы могли бы сделать что-то более причудливое, например, параболы (подгонка сплайнов), но, скорее всего, линейная интерполяция достаточно хороша.
2. Из того, что я могу сказать, вы хотите найти наибольшую разницу в значениях Y при двух значениях X. Я думаю, это означает, что две точки, которые вы проверяете, должны иметь одинаковое значение X. Итак, сравните количество точек в каждом ряду и перебирайте точки в ряду с наименьшим количеством точек. Также убедитесь, что две точки, которые вы сравниваете, имеют одинаковое значение X. // Если вы хотите пофантазировать, вы можете использовать метод регрессии, чтобы найти «недостающие» значения X из ряда с меньшим количеством точек, затем использовать функцию из регрессии для получения значения Y, а затем сравнить.
3. Вы хотите сказать, что хотите обрабатывать случаи, когда количество точек данных не одинаково между двумя рядами? Что вы хотите при необходимости выполнить интерполяцию между двумя точками, чтобы получить значение для сравнения с другими рядами?
4. Я не получаю «Точки [i]. YValues[0]» Как точка может иметь несколько значений y?
5. @Dennis_E в этом случае каждая точка i имеет одно значение y, и есть две серии, так что у вас есть два значения y, которые вы можете вычесть
Ответ №1:
Предполагается, что вы хотите выполнить какую-то интерполяцию между точками, если в двух рядах разное количество точек. Простая линейная интерполяция должна работать для достаточно большого количества точек, и поэтому весь алгоритм может выглядеть примерно так (в псевдокоде):
double distance = 0;
Series series1 = tmpChart.Series[series1];
Series series2 = tmpChart.Series[series2];
Series seriesToEnumerate = series1.Points.Count() >= series2.Points.Count() ? series1 : series2;
for (int i = 0; i < series1.Count(); i)
{
DataPoint point1 = series1.Points[i];
DataPoint point2 = series2.Points[i];
if (point1.X == point2.X)
{
distance = Math.Abs(point1.Y - point2.Y) // if greater than previous distance
}
else
{
// find two points in series2 whose X values surround point1.X, call them point3 and point4
// Interpolate between point3 and point4 to find the y value at the x of point1
double slope = (point4.Y - point3.Y) / (point4.X - point3.X);
double intercept = point4.Y - slope * point4.X;
double y2 = slope * point1.X intercept;
distance = Math.Abs(point1.Y - y2); // if this is greater than previous distance
}
}
Это простой пример алгоритма. Вы захотите очистить его, выполнить некоторую проверку ошибок, сделать его более эффективным и т.д.
Комментарии:
1. извините, но ваш пример не работает во многих точках (например, вы не можете преобразовать графики. Ввод данных в чертеж. Точка
point1 = series1.Points[i];
)2. Приведенный выше код является псевдокодом — его нельзя просто скопировать и скомпилировать. Вам нужно включить его в фактический код c #, который компилируется.
point1
иpoint2
являютсяDataPoint
объектами; Я отредактировал ответ, чтобы сделать его немного более понятным.3. Хорошо, это просто немного больше похоже на c #, чем на псевдокод, вот почему я это писал.
Ответ №2:
Если значения x не равны, увеличьте меньшее. (Это, вероятно, не самый эффективный способ; это просто для объяснения принципа)
public void MaxSpacing(object chart, int series1, int series2)
{
Chart tmpChart = (Chart)chart;
double distance = 0;
int position = 0;
for (int i = 0; i < tmpChart.Series[series1].Points.Count(); i ) {
if ((Math.Abs(tmpChart.Series[series1].Points[i].YValues[0] - tmpChart.Series[series2].Points[i].YValues[0])) > distance) {
distance = tmpChart.Series[series1].Points[i].YValues[0] - tmpChart.Series[series2].Points[i].YValues[0];
}
}
int len1 = tmpChart.Series[series1].Points.Count(), len2 = tmpChart.Series[series2].Points.Count();
for (int i1 = 0, i2 = 0; i1 < len1 amp;amp; i2 < len2;) {
var x1 = tmpChart.Series[series1].Points[i1].XValue;
var x2 = tmpChart.Series[series2].Points[i2].XValue;
if (x1 < x2) {
i1 ;
} else if (x2 < x1) {
i2 ;
} else {
double d = Math.Abs(tmpChart.Series[series1].Points[i1].YValues[0] - tmpChart.Series[series2].Points[i2].YValues[0]);
if (d > distance) {
distance = d;
position = i1; //I'm guessing here
}
i1 ;
i2 ;
}
}
}