簡體   English   中英

MSCharts自定義平移

[英]MSCharts custom panning

我正在嘗試在MSCharts(Microsoft圖表控件)中創建自己的自定義平移功能。 我意識到有一個用於縮放和平移的擴展,但是它沒有我想要的很多功能。 這是我目前擁有的平移功能:

//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像素,則該點仍將直接位於我的鼠標下方。 在我當前的視口中,這可行。 但是,如果我將圖表縮小或放大,則將無法正常工作。 當圖形變小時,圖形的移動速度比鼠標慢;當圖形變大時,圖形的移動速度比鼠標快。

我知道我應該以某種方式將視口或統計圖寬度包括在計算中,但是我真的不知道如何。 你們中有人有經驗嗎? 謝謝。

您很懷疑使用“標量”方法從像素中計算出一個因子的值是正確的。 這將永遠無法工作,原因不只一種。

但是無論如何,正確的解決方案要簡單得多。 它利用軸轉換功能之一在數據值和像素位置之間轉換。 (順便說一下,還有一個可以轉換成百分比位置的單位。)

我存儲初始位置以避免在鼠標移動過程中出現舍入錯誤:

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之外的InnerPlotPosition ,即Axis.LabelsTitlesLegend因為它們占用的空間不應縮放。

請注意,軸功能僅在PaintxxxMousexxx事件期間有效。

結果如下:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM