使用鼠标滚轮缩放会破坏 ZedGraph 中实时数据的平移(滚动)

Zooming with mouse wheel breaks panning (scrolling) of real time data in ZedGraph

Windows 在 WPF 应用程序中形成 ZedGraph 控件。数据点每 N 秒自动生成并附加到图表。当新数据点添加到图表时,我将图表向左移动(平移)一个点,因此视口中可见的点始终不超过最后 50 个点。总的来说,除了两点之外,它工作得很好。

问题

  1. 如果用户尝试放大或缩小,视口将停止跟随最后一个数据点并且图表会超出屏幕范围,因此平移将停止工作
  2. 我想在不滚动的情况下使用鼠标事件平移或移动图表,但是当我按下鼠标右键并尝试将其向左移动时,它会尝试缩放图表而不是平移
protected void CreateChart(ZedGraphControl control)
{
  _rand = new Random();

  var curve = control.GraphPane.AddJapaneseCandleStick("Demo", new StockPointList());

  curve.Stick.IsAutoSize = true;
  curve.Stick.Color = Color.Blue;

  control.AutoScroll = true; // Always shift to the last data point when new data comes in
  control.IsEnableHPan = true;  // I assume this should allow me to move chart to the left using mouse
  control.IsEnableVPan = true;
  control.IsEnableHZoom = true;
  control.IsEnableVZoom = true;
  control.IsShowPointValues = true;
  control.IsShowHScrollBar = false;
  control.IsShowVScrollBar = false;
  control.IsAutoScrollRange = true;  // Always shift to the last data point when new data comes in
  control.IsZoomOnMouseCenter = false;
  control.GraphPane.XAxis.Type = AxisType.DateAsOrdinal;
  control.AxisChange();
  control.Invalidate();

  var aTimer = new Timer();

  aTimer.Elapsed += new ElapsedEventHandler(OnTime);
  aTimer.Interval = 100;
  aTimer.Enabled = true;
}

protected XDate _xDate = new XDate(2006, 2, 1);
protected double _open = 50.0;
protected Random _rand = new Random();

// Auto generate data points

protected void OnTime(object source, ElapsedEventArgs e)
{
  var control = FormCharts;

  var x = _xDate.XLDate;
  var close = _open + _rand.NextDouble() * 10.0 - 5.0;
  var hi = Math.Max(_open, close) + _rand.NextDouble() * 5.0;
  var low = Math.Min(_open, close) - _rand.NextDouble() * 5.0;

  var pt = new StockPt(x, hi, low, _open, close, 100000);

  _open = close;
  _xDate.AddDays(1.0);

  if (XDate.XLDateToDayOfWeek(_xDate.XLDate) == 6)
  {
    _xDate.AddDays(2.0);
  }

  (control.GraphPane.CurveList[0].Points as StockPointList).Add(pt);

  control.GraphPane.XAxis.Scale.Min = control.GraphPane.XAxis.Scale.Max - 50; // Hide all points except last 50, after mouse zooming this line stops working
  //control.GraphPane.XAxis.Scale.Max = control.GraphPane.XAxis.Scale.Max + 1;
  control.AxisChange();
  control.Invalidate();
}

有点解决了。

缩放后自动滚动损坏的第一个问题

发生这种情况是因为缩放将这些参数设置为 FALSE。

area.XAxis.Scale.MinAuto = false;
area.XAxis.Scale.MaxAuto = false;

要修复它,请在每次出现新数据点时将其设置回 TRUE。另一种解决方法是将它们始终保持为 FALSE 并手动移动图表

protected void MoveChart(GraphPane pane, int pointsToMove, int pointsToShow)
{
  pane.XAxis.Scale.Max = pane.XAxis.Scale.Max - pointsToMove;
  pane.XAxis.Scale.Min = pane.XAxis.Scale.Max - Math.Abs(pointsToShow);
}

...

// Example : shift one point to the left and show only 50 last points

MoveChart(control.MasterPane.PaneList["Quotes"], -1, 50); 

第二期,使用鼠标事件实现无滚动条的自定义平移

protected int _mouseX = -1;
protected int _mouseY = -1;

... 

control.MouseUpEvent += OnMouseUp;
control.MouseDownEvent += OnMouseDown;
control.MouseMoveEvent += OnMouseMove;

...

// Example : remember X and Y on mouse down and move chart until mouse up event

protected bool OnMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
  _mouseX = -1; // unset X on mouse up
  _mouseY = -1;
  return true;
}

protected bool OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
  _mouseX = e.X; // remember last X on mouse down
  _mouseY = e.Y;
  return true;
}

protected bool OnMouseMove(ZedGraphControl sender, System.Windows.Forms.MouseEventArgs e)
{
  if (_mouseX >= 0) // if X was saved after mouse down
  {
    foreach (var pane in sender.MasterPane.PaneList) // move synced chart panels
    {
      MoveChart(pane, _mouseX > e.X ? -1 : 1, 50); // if mouse move is increasing X, move chart to the right, and vice versa
    }

    _mouseX = e.X; // update X to new position
    _mouseY = e.Y;
  }

  return true;
}