【问题标题】:MSCharts custom panningMSCharts 自定义平移
【发布时间】:2017-06-29 04:19:13
【问题描述】:

我正在尝试在 MSCharts(Microsoft Charting Controls)中创建自己的自定义平移功能。我意识到有一个缩放和平移的扩展,但是它没有我想要的很多功能。这是我目前拥有的平移功能:

//handles mouse panning, will pan while mouse left click if held down..
private int prevx = 0;
private int prevy = 0;
private void Mouse_Up(object sender, MouseEventArgs e)
{
    //reset previous x and y on mouse click up
    if (e.Button == MouseButtons.Left)
    {
        prevx = 0;
        prevy = 0;
    }
}
private void Mouse_Move(object sender, MouseEventArgs e, Chart chart)
{
    //if mouse was moved and mouse left click
    if (e.Button == MouseButtons.Left)
    {
        //a scalar, not entirely sure how useful it is, only works for my viewport
        double incr = 0.00130;

        if (prevx != 0 && prevy != 0)
        {
            //find x and y difference in mouse movement
            int diffx = e.X - prevx;
            int diffy = e.Y - prevy;

            //how much to increment x and y 
            double incrx = incr * Math.Abs(diffx);
            double incry = incr * Math.Abs(diffy);

            //get chart mins and maxs for both axes
            double minX = chart.ChartAreas[0].AxisX.Minimum;
            double maxX = chart.ChartAreas[0].AxisX.Maximum;
            double minY = chart.ChartAreas[0].AxisY.Minimum;
            double maxY = chart.ChartAreas[0].AxisY.Maximum;

            if (diffx > 0 && diffy > 0)
            {
                chart.ChartAreas[0].AxisX.Minimum -= (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisX.Maximum -= (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisY.Minimum += (maxY - minY) * incry;
                chart.ChartAreas[0].AxisY.Maximum += (maxY - minY) * incry;
                //Console.WriteLine("upleft");
            }
            else if (diffx < 0 && diffy > 0)
            {
                chart.ChartAreas[0].AxisX.Minimum += (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisX.Maximum += (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisY.Minimum += (maxY - minY) * incry;
                chart.ChartAreas[0].AxisY.Maximum += (maxY - minY) * incry;
                //Console.WriteLine("upright");
            }
            else if (diffx > 0 && diffy < 0)
            {
                chart.ChartAreas[0].AxisX.Minimum -= (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisX.Maximum -= (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisY.Minimum -= (maxY - minY) * incry;
                chart.ChartAreas[0].AxisY.Maximum -= (maxY - minY) * incry;
                //Console.WriteLine("bottom left");
            }
            else if (diffx < 0 && diffy < 0)
            {
                chart.ChartAreas[0].AxisX.Minimum += (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisX.Maximum += (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisY.Minimum -= (maxY - minY) * incry;
                chart.ChartAreas[0].AxisY.Maximum -= (maxY - minY) * incry;
                //Console.WriteLine("bottomright");
            }
            else if (diffx > 0 && diffy == 0)
            {
                chart.ChartAreas[0].AxisX.Minimum -= (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisX.Maximum -= (maxX - minX) * incrx;
                //Console.WriteLine("right");
            }
            else if (diffx < 0 && diffy == 0) 
            {
                chart.ChartAreas[0].AxisX.Minimum += (maxX - minX) * incrx;
                chart.ChartAreas[0].AxisX.Maximum += (maxX - minX) * incrx;
                //Console.WriteLine("left");
            }
            else if (diffy > 0 && diffx == 0)
            {
                chart.ChartAreas[0].AxisY.Minimum += (maxY - minY) * incry;
                chart.ChartAreas[0].AxisY.Maximum += (maxY - minY) * incry;
                //Console.WriteLine("down");
            }
            else if (diffy < 0 && diffx == 0) 
            {
                chart.ChartAreas[0].AxisY.Minimum -= (maxY - minY) * incry;
                chart.ChartAreas[0].AxisY.Maximum -= (maxY - minY) * incry;
                //Console.WriteLine("up");
            }
        }
        prevx = e.X;
        prevy = e.Y;
    }
}

我注意到有一个类似的问题,尽管它是在我没有经验的 JavaFX 中。我设想的平移功能应该能够随着图形移动鼠标。因此,如果我单击某个点,向左拖动 50 像素,该点仍将直接位于我的鼠标下方。在我当前的视口中,这是可行的。但是,如果我使图表变小或变大,事情就不起作用了。当图形变小时,图形移动得比我的鼠标慢,当图形变大时,图形移动得比我的鼠标快。

我知道我可能应该以某种方式将视口或图表宽度包含在计算中,但我真的不知道如何。你们有这方面的经验吗?谢谢。

【问题讨论】:

  • 最重要的是,您应该解释您缺少哪些功能以及它们应该如何工作..
  • @TaW,我编辑了帖子,希望底部能解释发生了什么。

标签: c# mschart


【解决方案1】:

您完全正确地怀疑“标量”方法来计算像素值的一个因素。这永远不会奏效,而且原因不止一个..

但无论如何,正确的解决方案要简单得多。它利用轴转换功能之一在数据值和像素位置之间进行转换。 (还有一个可以转换为百分比位置,顺便说一句..)

我存储初始位置以避免鼠标移动过程中的舍入误差:

private double prevXMax = 0;
private double prevXMin = 0;
private double prevYMax = 0;
private double prevYMin = 0;
private Point mDown = Point.Empty;

我们现在只需要Mousedown

private void chart_MouseDown(object sender, MouseEventArgs e)
{
    //store previous data
    if (e.Button == MouseButtons.Left)
    {
        mDown = e.Location;
        prevXMax = chart.ChartAreas[0].AxisX.Maximum;
        prevXMin = chart.ChartAreas[0].AxisX.Minimum;
        prevYMax = chart.ChartAreas[0].AxisY.Maximum;
        prevYMin = chart.ChartAreas[0].AxisY.Minimum;
    }
}

还有更简单的MouseMove

private void chart_MouseMove(object sender, MouseEventArgs e)
{
    Axis ax = chart.ChartAreas[0].AxisX;
    Axis ay = chart.ChartAreas[0].AxisY;

    //if mouse was moved and mouse left click
    if (e.Button == MouseButtons.Left)
    {
        double x0 = ax.PixelPositionToValue(mDown.X);
        double x1 = ax.PixelPositionToValue(e.X);
        double y0 = ay.PixelPositionToValue(mDown.Y);
        double y1 = ay.PixelPositionToValue(e.Y);

        ax.Minimum = prevXMin + (x0 - x1);
        ax.Maximum = prevXMax + (x0 - x1);
        ay.Minimum = prevYMin + (y0 - y1);
        ay.Maximum = prevYMax + (y0 - y1);
    }
}

缩放计算的一个问题是您可能想要调整图表的大小;在那之后,规模将不再起作用。另一个是你必须取出ChartAreaInnerPlotPosition之外的东西,即Axis.LabelsTitlesLegend,因为它们占用的空间不应该被缩放。

注意轴函数仅在PaintxxxMousexxx 事件期间有效..

结果如下:

【讨论】:

    猜你喜欢
    • 2017-03-02
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 2012-05-02
    • 1970-01-01
    相关资源
    最近更新 更多