ChartDirector放大(Zoom In)和缩小(Zoom Out)

By | 2018年5月4日

1. 设定Zoom方向

ChartViewer—setZoomDirection(int)

  • Chart.DirectionHorizontalVertical:可以画任意矩形放大,点击也触发放大。
  • Chart.DirectionHorizontal:水平方向画矩形,高度和plot area一样高。
  • Chart.DirectionVertical:垂直方向画决心,宽度和plot area一样宽。
chartViewer.setZoomDirection(Chart.DirectionHorizontalVertical);

2. 添加按钮

通常情况下,我们需要三个按钮,用于修改鼠标形状,并执行zoom行为。

2.1. Pointer按钮

将鼠标恢复成默认手势。

private void pointerAction() {
  chartViewer.setMouseUsage(Chart.MouseUsageDefault);
}

2.2. Zoom in按钮

鼠标变成放大图标,此时用户可以拖画矩形放大或点击放大。

private void zoomInAction() {
  chartViewer.setMouseUsage(Chart.MouseUsageZoomIn);
}

2.3. Zoom out按钮

鼠标变成缩小图标,点击plot area缩小。

private void zoomOutAction() {
  chartViewer.setMouseUsage(Chart.MouseUsageZoomOut);
}

3. ChartViewer监听view port更改事件

View port更改后,通常我们就是重新绘制plot,下面调用的refresh()方法就是在创建新的chart。

chartViewer.addViewPortListener(new ViewPortAdapter() {
  @Override
  public void viewPortChanged(ViewPortChangedEvent event) {
    viewPortChangedAction(event);
  }
});

private void viewPortChangedAction(ViewPortChangedEvent event) {
  if (event.needUpdateChart()) {
    refresh();
  }
}

4. 根据view port创建新chart

4.1. 回收旧chart

因为在不停的创建,所以要回收旧的chart资源。

XYChart chart = new XYChart(...);
chart.recycle(chartViewer.getChart());

4.2. Clip plot area

当使用缩放时,chartdirector会把多余部分,画在坐标轴外面。为了美观,不让在plot area之外绘制东西。

chart.setClipping();

4.3. 定义初始范围

XYChart—setFullRange(String, double, double),表示显示多少,如果不设置默认显示所有,chartdirector还留些margin:

  • 参数1:哪个坐标轴,x,y或z;
  • 参数2:最小值;
  • 参数3:最大值。

注意:

Axis—setLinear(double, double),指定坐标轴范围,范围之外不显示。setFullRange(…)只是指定100%缩放时的大小,范围之外的显示在plot area外面了。

4.4. 同步坐标轴和view port

同步一下,让chart viewer只显示view port里面的内容。

chartViewer.syncLinearAxisWithViewPort("x", chart.xAxis());
chartViewer.syncLinearAxisWithViewPort("y", chart.yAxis());

4.5. Clip draw area

一定要在sync完坐标轴(步骤4.4)后,再clip draw area,否则下面计算value和坐标都是错的。不clip draw area,会导致绘制在坐标轴之外,特别丑。

double leftVal = chartViewer.getValueAtViewPort("x", chartViewer.getViewPortLeft());
double rightVal = chartViewer.getValueAtViewPort("x",
    chartViewer.getViewPortLeft() + chartViewer.getViewPortWidth());

double topVal = chartViewer.getValueAtViewPort("y",
    1 - chartViewer.getViewPortTop());
double bottomVal = chartViewer.getValueAtViewPort("y",
    1 - chartViewer.getViewPortTop() - chartViewer.getViewPortHeight());

drawArea.setClipRect(chart.getXCoor(leftVal), chart.getYCoor(topVal),
    chart.getXCoor(rightVal), chart.getYCoor(bottomVal));