2

DateTime動的データ表示プロットと値を使用してリアルタイム チャートを作成しようとしていIntegerます。私が必要としているのは、軸の値が固定された X 軸のスムーズなスクロールです。パンと同じように、つまりプロットを中心からドラッグすると、マウス カーソルでスムーズに流れます。同様の動作を自動的に行いたいと思います。

現在、タイマーでデータ ソースを変更すると、軸の範囲が動的に変更され、スクロールがスムーズになりません。この動作を変更することは可能ですか。どんなアイデアでも、助けてください。

日付と整数のデータソースを 400 ミリ秒のタイマーで動的に更新しようとしました。これにより、データソースに基づいて軸範囲が変化するリアルタイム グラフが生成されます。

テストコードは次のとおりです。

ウィンドウロード時

 timer = new Timer(400);
 ds = new ObservableDataSource<VoltagePoint>();
 ds.SetXMapping(x => dateAxis.ConvertToDouble(x.Date));
 ds.SetYMapping(y => y.Voltage);
 plotter.AddLineGraph(ds, 2, "Sample");
 timer.Start();

オンタイマーティック

 Random rnd = new Random();
 TestPoint pt = new TestPoint (rnd.Next(1, 500), DateTime.Now);
 ds.AppendAsync(plotter.Viewport.Dispatcher, pt);
4

1 に答える 1

2

私はあなたがこのようなものを求めていると信じています:

// Your code (unchanged)
timer = new Timer(400);
ds = new ObservableDataSource<VoltagePoint>();
ds.SetXMapping(x => dateAxis.ConvertToDouble(x.Date));
ds.SetYMapping(y => y.Voltage);
plotter.AddLineGraph(ds, 2, "Sample");
timer.Start();

// Make the Viewport not move when items are added.
plotter.Viewport.AutoFitToView = false;

// Put in your initial viewing dimensions
var xMin = dateAxis.ConvertToDouble(DateTime.Now);
var startXMax = dateAxis.ConvertToDouble(DateTime.Now.AddMinutes(1));
var startYMin = -20;
var startYMax = 520;

// Set the initial visible area.
plotter.Visible = new Rect { X = xMin, Width = startXMax - xMin, Y = startYMin, Height = startYMax - startYMin };

// If you wish, you can also restrict where the user can scroll:
plotter.Viewport.Restrictions.Add(new CustomAxisRestriction(xMin));

制限がユーザーに表示されるものを制御する別の方法である場合、非常に基本的な例を以下に示します。

    public class CustomAxisRestriction : ViewportRestrictionBase
    {
        private double xMin;
        public CustomAxisRestriction(double xMin)
        {
            this.xMin = xMin;
        }
        public override Rect Apply(Rect oldDataRect, Rect newDataRect, Viewport2D viewport)
        {
            newDataRect.X = Math.Max(newDataRect.X, xMin);
            return newDataRect;
        }
    }

基本的に、制限で必要なのはApply、上記のシグネチャを使用してメソッドをオーバーライドすることだけです。

あなたの場合、 -20 <-> 520 (またはしかし) に制限したい場合は、newDataRect.Yとに制限を追加することもできnewDataRect.Heightますが、それはあなたに任せます - 基本的な考え方は上記のとおりです。

お役に立てれば!上記のいずれかが意味をなさない場合はお知らせください:)。

スムーズなスクロールのための(必ずしも素晴らしいとは限りません)方法:

たとえば、初期化時に別のタイマーを追加します。

        animationTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(20) };
        animationTimer.Tick += animationTimer_Tick;
        animationTimer.Start();

の移動はUI スレッドで行う必要があるため、 a のDispatcherTimer代わりに aを使用します。次に、次のようにします。TimerViewPort

    private void animationTimer_Tick(object sender, EventArgs e)
    {
        var oldRect = plotter.Visible;
        oldRect.X = Math.Max(oldRect.X, dateAxis.ConvertToDouble(DateTime.Now.AddMinutes(-0.1)));
        plotter.Visible = oldRect;
    }

もちろん、UX の観点から、ユーザーがこのスクロールを中断して再度有効にする方法/かどうかを慎重に検討する必要があります。しかし、私はそれをあなたに任せます..!

しかし、上記のコードはすべて動作するはずです (または、少なくともローカルで動作していました!) 問題があればお知らせください。

アニメーション中に軸が奇妙な動作をするといういくつかの問題がありました。これは基本的に軸のちょっとしたバグだと思うので、必要に応じて、独自の :を継承しTicksProviderて実装する必要があるかもしれませんGoogle 検索で簡単に実装できます。dateAxis.TicksProvider = new CustomTicksProvider();CustomTicksProviderTimeTicksProviderBase<DateTime>

幸運を!

于 2014-09-12T13:27:24.710 に答える