简体   繁体   English

X轴上的自动缩放Y轴缩放

[英]Auto Zoom Y Axis on X Axis Zoom

Yes i know about ( This post ) , if you search you will notice the event AxisValueChanged seems to only exist in this one thread. 是的,我知道( 这篇文章 ),如果你搜索你会注意到事件AxisValueChanged似乎只存在于这一个线程中。

My goal is simply to automaticly zoom the Y axis when user make a selection on the X axis, but i have been unable to figure out how. 我的目标只是在用户在X轴上进行选择时自动缩放Y轴,但我一直无法弄清楚如何。

I also tried to to use the SelectionRangeChanged event, but this event seems kind of broken as im unable to figure out whats actual range selected? 我也尝试使用SelectionRangeChanged事件,但这个事件似乎有点破,因为我无法弄清楚什么是实际范围选择? ( IE so i can find the maximum / minimum ranges ). (IE所以我可以找到最大/最小范围)。

Im using MS chart ( Microsoft chart ) 我用MS图表(微软图表)

The end goal is when i zoom X axis ( This is a FastLine Chart) it should see the new "max" visible value on Y axis and resize/zoom it accordingly 最终目标是当我缩放X轴(这是一个FastLine图表)时,它应该在Y轴上看到新的“max”可见值并相应地调整它/缩放它

If I understand you correctly, given a zoomed range on X axis you want to zoom also the same range on Y axis. 如果我理解正确,给定X轴上的缩放范围,您想要在Y轴上缩放相同的范围。 If so, you can do in this way: 如果是这样,你可以这样做:

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);
}

As you said, the event AxisValueChanged doesn't exist; 如你所说,事件AxisValueChanged不存在; the post you linked probably meant the (existing) event AxisViewChanged . 您链接的帖子可能意味着(现有)事件AxisViewChanged

Obviously, you can also use AxisViewChanged for your purpose, and adapting my code to exploit that event shouldn't be so hard. 显然,您也可以将AxisViewChanged用于您的目的,并且调整我的代码以利用该事件不应该那么难。

Feel free to ask if you need help though ;) 请随时询问您是否需要帮助;)

EDIT : 编辑:

I modified my code to account for your goal. 我修改了我的代码以说明您的目标。 The following code computes the Y range corresponding to the maximum and minimum values of the points inside the zoomed X range: 以下代码计算与缩放X范围内的点的最大值和最小值对应的Y范围:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM