【问题标题】:Auto Zoom Y Axis on X Axis Zoom在 X 轴缩放上自动缩放 Y 轴
【发布时间】:2012-04-17 16:53:05
【问题描述】:

是的,我知道(This post),如果您搜索,您会注意到事件AxisValueChanged 似乎只存在于这一线程中。

我的目标只是当用户在 X 轴上进行选择时自动缩放 Y 轴,但我一直无法弄清楚如何。

我也尝试使用 SelectionRangeChanged 事件,但这个事件似乎有点坏,因为我无法弄清楚选择的实际范围是什么? (IE 所以我可以找到最大/最小范围)。

我使用的是 MS 图表(微软图表)

最终目标是当我缩放 X 轴(这是一个快速折线图)时,它应该在 Y 轴上看到新的“最大”可见值并相应地调整/缩放它

【问题讨论】:

    标签: c# mschart


    【解决方案1】:

    如果我理解正确,给定 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 用于您的目的,并且调整我的代码以利用该事件应该不难。

    如果您需要帮助,请随时询问;)

    编辑:

    我修改了代码以实现您的目标。以下代码计算缩放后的 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);
    }
    

    【讨论】:

    • 这完全符合我的解释,我稍微更新了解释以明确我的最终目标。明天我会亲自测试更多:) 谢谢
    猜你喜欢
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2011-10-20
    相关资源
    最近更新 更多