2012-04-17 10 views
4

Да, я знаю о (This post), при поиске вы заметите, что событие AxisValueChanged, похоже, существует только в этой теме.Автомасштабирование оси Y на оси X Zoom

Моя цель - просто автоматическое масштабирование оси Y, когда пользователь делает выбор по оси X, но мне не удалось выяснить, как это сделать.

Я также пытался использовать событие SelectionRangeChanged, но это событие вроде бы сломано, так как им не удалось определить, какой диапазон выбран? (IE, поэтому я могу найти максимальные/минимальные диапазоны).

Im с использованием диаграммы MS (диаграмма Microsoft)

Конечная цель, когда я увеличить ось X (Это диаграмма FastLine) он должен увидеть новый «Макс» видимое значение на оси Y и размер/увеличить его соответственно

ответ

5

Если я правильно вас понимаю, учитывая увеличенный диапазон по оси X, вы хотите увеличить масштаб в том же диапазоне по оси Y. Если да, то вы можете сделать так:

void chart1_SelectionRangeChanged(object sender, CursorEventArgs e) 
{ 
    // Given the visible (zoomed) range on X, 
    // it zooms the same relative range on Y: 
    // i.e. if on the X axis, the range 5% - 30% is zoomed, 
    // it zooms the same range on Y. 
    var axisY = this.chart1.ChartAreas[0].AxisY; 

    var totalXRange = e.Axis.Maximum - e.Axis.Minimum; 
    var totalYRange = axisY.Maximum - axisY.Minimum; 

    var ySelectionStart = (e.Axis.ScaleView.ViewMinimum - e.Axis.Minimum) * 
          totalYRange/totalXRange; 
    var ySelectionEnd = (e.Axis.ScaleView.ViewMaximum - e.Axis.Minimum) * 
         totalYRange/totalXRange; 

    axisY.ScaleView.Zoom(ySelectionStart,ySelectionEnd); 
} 

Как вы сказали, событие AxisValueChanged не существует; связанное с вами сообщение, вероятно, означало (существующее) событие AxisViewChanged.

Очевидно, вы также можете использовать AxisViewChanged для своей цели, а адаптация моего кода для использования этого события не должна быть такой сложной.

Не стесняйтесь спрашивать, если вам нужна помощь, хотя;)

EDIT:

Я изменил мой код, чтобы объяснить цели. Следующий код вычисляет диапазон Y, соответствующий максимальным и минимальным значениями точек внутри увеличенного диапазона X:

void chart1_SelectionRangeChanged(object sender, CursorEventArgs e) 
{ 
    var axisY = this.chart1.ChartAreas[0].AxisY; 

    var xRangeStart = e.Axis.ScaleView.ViewMinimum; 
    var xRangeEnd = e.Axis.ScaleView.ViewMaximum; 

    // compute the Y values for the points crossing the range edges 
    double? yRangeStart = null; 
    var pointBeforeRangeStart = this.chart1.Series[0].Points.FirstOrDefault(x => x.XValue <= xRangeStart); 
    var pointAfterRangeStart = this.chart1.Series[0].Points.FirstOrDefault(x => x.XValue > xRangeStart); 
    if (pointBeforeRangeStart != null && pointAfterRangeStart != null) 
     yRangeStart = Interpolate2Points(pointBeforeRangeStart, pointAfterRangeStart, xRangeStart); 

    double? yRangeEnd = null; 
    var pointBeforeRangeEnd = this.chart1.Series[0].Points.FirstOrDefault(x => x.XValue <= xRangeEnd); 
    var pointAfterRangeEnd = this.chart1.Series[0].Points.FirstOrDefault(x => x.XValue > xRangeEnd); 
    if (pointBeforeRangeEnd != null && pointAfterRangeEnd != null) 
     yRangeEnd = Interpolate2Points(pointBeforeRangeEnd, pointAfterRangeEnd, xRangeEnd); 

    var edgeValues = new[] { yRangeStart, yRangeEnd }.Where(x => x.HasValue).Select(x => x.Value); 

    // find the points inside the range 
    var valuesInRange = this.chart1.Series[0].Points 
    .Where(p => p.XValue >= xRangeStart && p.XValue <= xRangeEnd) 
    .Select(x => x.YValues[0]); 

    // find the minimum and maximum Y values 
    var values = valuesInRange.Concat(edgeValues); 
    double yMin; 
    double yMax; 
    if (values.Any()) 
    { 
     yMin = values.Min(); 
     yMax = values.Max(); 
    } 
    else 
    { 
     yMin = this.chart1.Series[0].Points.Min(x => x.YValues[0]); 
     yMax = this.chart1.Series[0].Points.Max(x => x.YValues[0]); 
    } 

    // zoom Y-axis to [yMin - yMax] 
    axisY.ScaleView.Zoom(yMin, yMax); 
} 

// see: http://en.wikipedia.org/wiki/Linear_interpolation#Linear_interpolation_between_two_known_points 
public static double Interpolate2Points(DataPoint p1, DataPoint p2, double x) 
{ 
    var x0 = p1.XValue; 
    var y0 = p1.YValues[0]; 
    var x1 = p2.XValue; 
    var y1 = p2.YValues[0]; 
    return y0 + ((x - x0) * y1 - (x - x0) * y0)/(x1 - x0); 
} 
+0

Это работает отлично, как я объяснил, я обновленное ОБЪЯСНЕНИЕ немного, чтобы сделать мою цель конца ясна. Il personaly test больше завтра :) Спасибо – EKS

+0

@EKS: отредактирован для учета ваших изменений;) – digEmAll