I'm trying to work with ClusteredXYBarRenderer while creating a XYBarChart. This chart in itself has multiple data series added to it. My requirement is to allow the users to zoom in on the domain axis whilst preventing zoom on the range axis. This I could easily implement in my code.
However what I getting stuck at is the following requirement:
- The ability to zoom only to a specific level on the domain axis. i.e. I do NOT want users to zoom on fractional values. If the domain contains value {3, 4, 5....}, the users can maximum zoom in to see {3, 4}, etc but not {3, 3.5, 3.75....}
- Add spacing between the start/end of domain data points, for example: bar1, bar2, bar3 (x-value= 1) [gap] bar1, bar2, bar3 (x-value= 2), This way, it would be easier for the user to differentiate where one set of values start and where do they end.
Here's an SSCCE for your reference:
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.ClusteredXYBarRenderer;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
public class ClusteredBarChart {
private JFreeChart createClusteredChart(String title, String categoryAxisLabel, String valueAxisLabel, IntervalXYDataset dataset) {
NumberAxis domainAxis = new NumberAxis(categoryAxisLabel);
domainAxis.setAutoRangeIncludesZero(false);
domainAxis.setAutoRange(true);
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
XYBarRenderer renderer = new ClusteredXYBarRenderer();
renderer.setShadowVisible(false);
XYPlot plot = new XYPlot(dataset, domainAxis, valueAxis, renderer);
plot.setOrientation(PlotOrientation.VERTICAL);
plot.setNoDataMessage("=== No Datapoints Detected ====");
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
return chart;
}
private void createDummyData(XYSeriesCollection intervalDataset){
XYSeries series1 = new XYSeries("series1");
XYSeries series2 = new XYSeries("series2");
XYSeries series3 = new XYSeries("series3");
XYSeries series4 = new XYSeries("series4");
XYSeries series5 = new XYSeries("series5");
series1.add(6, 10);
series1.add(7, 11);
series1.add(10, 11);
series1.add(17, 17);
series1.add(21, 15);
series2.add(6, 18);
series2.add(7, 10);
series2.add(10, 14);
series2.add(17, 12);
series2.add(21, 6);
series3.add(6, 12);
series3.add(7, 13);
series3.add(10, 14);
series3.add(17, 16);
series3.add(21, 9);
series4.add(6, 8);
series4.add(7, 22);
series4.add(10, 21);
series4.add(17, 26);
series4.add(21, 24);
series5.add(6, 14);
series5.add(7, 11);
series5.add(10, 31);
series5.add(17, 12);
series5.add(21, 11);
intervalDataset.addSeries(series1);
intervalDataset.addSeries(series2);
intervalDataset.addSeries(series3);
intervalDataset.addSeries(series4);
intervalDataset.addSeries(series5);
}
public void doPlot(String plotTitle) {
XYSeriesCollection intervalXYDataSet = new XYSeriesCollection();
createDummyData(intervalXYDataSet);
JFreeChart chart = createClusteredChart(plotTitle, "Category", "Value", intervalXYDataSet);
ChartPanel chartpanel = new ChartPanel(chart);
chartpanel.setDomainZoomable(true);
chartpanel.setRangeZoomable(false);
JFrame frame = new JFrame();
frame.setTitle(plotTitle);
frame.add(new JScrollPane(chartpanel));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new ClusteredBarChart().doPlot("Test Plot");
}
}
If you run the example, you would see that the points for value #6 and #7 appears real close. I want to add space in between them. Also, I want to prevent users to zoom in to 6.5 or 6.75, etc....in other words, the max zoom-able range should be the values present in the actual data set.
Note that this questions has a reference to this one that I had asked earlier.
Any help would be really appreciated. Thanks!