JFreeChart with XYBoxAnnotation Open on One Side

↘锁芯ラ 提交于 2021-01-28 08:08:20

问题


I'm using an XYBoxAnnotation to demarcate a rectangular area on a JFreeChart. I would like one side of the box to be "open", i.e go out to infinity. I tried setting the value to Double.POSITIVE_INFINITY but this did not seem to work. I also tried setting it to Double.MAX_VALUE, with no luck either. In these cases, the annotation doesn't even show up on the plot at all. And there are no exceptions thrown.

Below is a very simple version of my code in which I generate the XYBoxAnnotation and add it to the plot.

XYBoxAnnotation _axisMarker = new XYBoxAnnotation(xLow, yLow, Double.POSITIVE_INFINITY, yHigh, new BasicStroke(0.5F), Color.WHITE, Color.WHITE);
_plot.getRenderer().addAnnotation(_axisMarker, Layer.BACKGROUND);

EDIT:

I figured out that the reason the annotation wasn't showing up was because the x value for the annotation was much much larger than the axis scale. For some reason, this causes the annotation to not be visible until you zoom out enough.

Thanks to @trashgod's answer below, I came up with a solution. His answer didn't quite work for me since my plot allows zooming and you could see the edge of the box when you zoomed out.

First, I added a PlotChangeListener to listen for when the plot is zoomed:

// define PlotChangeListener to update the annotation when the plot is zoomed
private PlotChangeListener _zoomListener = new PlotChangeListener() {
  @Override
  public void plotChanged(PlotChangeEvent plotChangeEvent) {
    if (_basisIsotope != null) {
      updateAxisMarkers();
    }
  }
};

Then I created a function to re-draw the annotation based on the new plot bounds:

// function to re-draw the annotation
private void updateAxisMarkers() {
  _plot.removeChangeListener(_zoomListener); // remove to prevent triggering infinite loop

  // define xLow, yLow and yHigh...

  double xHigh = _plot.getDomainAxis().getUpperBound() * 1.1;
  XYBoxAnnotation _axisMarker = new = new XYBoxAnnotation(xLow, yLow, xHigh, yHigh, new BasicStroke(0.5F), Color.WHITE, Color.WHITE);
  _plot.getRenderer().addAnnotation(annotation);

  _plot.addChangeListener(_zoomListener); // add back
}

回答1:


Double.MAX_VALUE is too large to scale to the relevant axis, but Double.MAX_VALUE / 2 works as well as any value larger than the upper bound of the axis. A better choice might be a value that exceeds the maximum value of the domain by some margin. The fragment below shades a plot of some Gaussian data with an XYBoxAnnotation that has domain bounds extending from 42 to the maximum domain value + 10%; the range bounds are ±1σ.

XYSeriesCollection dataset = createDataset();
JFreeChart chart = createChart(dataset);
Color color = new Color(0, 0, 255, 63);
double max = dataset.getSeries(0).getMaxX() * 1.1;
XYBoxAnnotation annotation = new XYBoxAnnotation(
    42, -1, max, 1, new BasicStroke(1f), color, color);
chart.getXYPlot().getRenderer().addAnnotation(annotation);



来源:https://stackoverflow.com/questions/44703056/jfreechart-with-xyboxannotation-open-on-one-side

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!