3

X軸の値を右にドラッグしてから新しい場所にドロップすることにより、.NETグラフを使用してグラフのズームを実装しようとしています。それは一種の働きですが、私はいくつかの問題を抱えています。これが私のコードです:

public partial class ChartForm : Form
{
    public ChartForm()
    {
        InitializeComponent();
    }

    private Axis AxisX { get; set; }
    private double InitialAxisValue { get; set; }

    protected override void OnLoad(EventArgs e)
    {
        chart1.Series.Add(CreateDataSeries());
        AxisX = chart1.ChartAreas[0].AxisX;
        InitialAxisValue = double.NaN;
        chart1.MouseMove += OnChartMouseMove;
        chart1.MouseDown += OnChartMouseDown;
        chart1.MouseUp += OnChartMouseUp;
    }

    private static Series CreateDataSeries()
    {
        var dataSeries = new Series
                             {
                                 ChartType = SeriesChartType.Line,
                             };

        for (double spotPrice = 1100; spotPrice < 1300; spotPrice++)
        {
            dataSeries.Points.Add(new DataPoint(spotPrice, spotPrice));
        }

        return dataSeries;
    }

    private void OnChartMouseUp(object sender, MouseEventArgs e)
    {
        InitialAxisValue = double.NaN;
    }

    private void OnChartMouseDown(object sender, MouseEventArgs e)
    {
        if (!MouseOnXAxis(e.X, e.Y))
            return;

        double valueX = AxisX.PixelPositionToValue(e.X);
        InitialAxisValue = valueX;
    }

    private void OnChartMouseMove(object sender, MouseEventArgs e)
    {
        try
        {
            Cursor = MouseOnXAxis(e.X, e.Y) ? Cursors.Hand : Cursors.Default;
            HandleZoom(e);
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }

    private void HandleZoom(MouseEventArgs e)
    {
        if (double.IsNaN(InitialAxisValue))
            return;

        AxisX.Maximum = GetNewAxisMaximumValue(e.X, InitialAxisValue);
    }

    private double GetNewAxisMaximumValue(double currentAxisCoordinate,
                                          double initialAxisZoomPointValue)
    {
        double axisMinimumValue = AxisX.Minimum;
        double axisMaximumValue = AxisX.Maximum;
        double axisMinimumCoordinate = AxisX.ValueToPixelPosition(axisMinimumValue);
        double axisMaximumCoordinate = AxisX.ValueToPixelPosition(axisMaximumValue);
        double relativePos = (currentAxisCoordinate - axisMinimumCoordinate) /
                             (axisMaximumCoordinate - axisMinimumCoordinate);
        double newAxisWidth = ((initialAxisZoomPointValue - axisMinimumValue)/relativePos);
        return axisMinimumValue + newAxisWidth;
    }

    private bool MouseOnXAxis(int xCoor, int yCoor)
    {
        HitTestResult hitTestResult = chart1.HitTest(xCoor, yCoor);
        return hitTestResult.ChartElementType == ChartElementType.AxisLabels &&
               hitTestResult.Axis == AxisX;
    }
}

実際のズーム効果は、HandleZoom()でAxisXの最大値を変更することで発生します。

AxisX.Maximum = GetNewAxisMaximumValue(e.X, InitialAxisValue);

ここで、「InitialAxisValue」は初期ドラッグ値であり、「eX」は現在のマウスのx軸座標です。

動作しますが、問題があります。ドラッグの動きがスムーズでない場合や、チャート/グリッドで不要な動きや点滅が発生する場合があります(マウスをゆっくりと右にドラッグすると簡単に確認できます)。

問題はおそらくHandleZoom()とGetNewAxisMaximumValue()の実装にあります。

どんな助けでも素晴らしいでしょう。

ありがとう

4

3 に答える 3

2

ズーム機能は既に解決されていますが、組み込みの .net チャート ズーム オプションを使用しないのはなぜですか?

chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
于 2013-01-28T10:49:56.583 に答える
2

解決しました!

私のズーム計算は、ピクセル単位の X 軸の幅が固定されているという前提に基づいており、明らかに InnerPlotPosition プロパティが TRUE に設定されている場合、ピクセル単位の X 軸の幅は、たとえばズーム中に実行時に変更される可能性があります。

したがって、解決策はInnerPlotPositionプロパティを FALSE に設定し、内側のプロット エリアを手動で設定することです。

        chart1.ChartAreas[0].InnerPlotPosition.Auto = false;
        chart1.ChartAreas[0].InnerPlotPosition.Height = 80.29209F;
        chart1.ChartAreas[0].InnerPlotPosition.Width = 85F;
        chart1.ChartAreas[0].InnerPlotPosition.X = 15F;
        chart1.ChartAreas[0].InnerPlotPosition.Y = 5.07246F;
于 2012-12-22T22:18:47.157 に答える
0

グラフ コントロールの "DoubleBuffer = true" は役に立ちますか?

于 2012-12-22T14:05:49.830 に答える