Im build a series graph with jfreechart using XYLineAndShapeRenderer, this series need to show values for each day of a month, then I need that the X axis shows values from 1 to 30 or 1 to 31 (depend of current month). The dataset only have X values from 1 to 30/31, but the resultant graph shows ZERO(before 1) and 31/32 after(30/31). I want to show only 1 to 30/31 on X axis. But I dont have success. Follow shows the code that build dataset and graph and resultante image. How I can show only valid values on X axis in this case ?
// build dataset
private XYDataset createSampleData()
{
List<Integer> diario = new ArrayList<>(Arrays.asList(20, 50, 120, 78, 37, 69, 145));
int dSize = diario.size();
int dPos = 0;
XYSeries serieD = new XYSeries("Diário");
XYSeries serieA = new XYSeries("Acumulado");
int acumulado = 0;
for(int i=1; i < 31; i++) {
int valDay = diario.get(dPos++);
acumulado += valDay;
serieD.add(i, valDay);
serieA.add(i, acumulado);
if( dPos >= dSize ) {
dPos = 0;
}
}
XYSeriesCollection result = new XYSeriesCollection(serieD);
result.addSeries(serieA);
return result;
}
private JFreeChart buildSeriesChartBySeriesData(String title, String labelX, String labelY)
{
NumberAxis xAxis = new NumberAxis(labelX);
xAxis.setAutoRangeIncludesZero(false);
xAxis.setRangeType(RangeType.POSITIVE);
NumberAxis yAxis = new NumberAxis(labelY);
yAxis.setAutoRangeIncludesZero(false);
yAxis.setRangeType(RangeType.POSITIVE);
XYSplineRenderer renderer1 = new XYSplineRenderer();
XYPlot plot = new XYPlot(this.createSampleData(), xAxis, yAxis, renderer1);
plot.setDomainGridlinesVisible(true);
plot.setDomainZeroBaselineVisible(false);
plot.setDomainPannable(false);
plot.setBackgroundPaint(new Color(224, 224,235));
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
plot.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
plot.setDomainPannable(false);
plot.setRangePannable(false);
plot.setDomainZeroBaselineVisible(false);
plot.setRangeZeroBaselineVisible(false);
renderer1.setSeriesPaint(0, Color.blue);
renderer1.setSeriesPaint(1, Color.yellow);
plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3));
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
XYLineAndShapeRenderer localXYLineAndShapeRenderer = (XYLineAndShapeRenderer) plot.getRenderer();
localXYLineAndShapeRenderer.setBaseShapesVisible(true);
localXYLineAndShapeRenderer.setBaseShapesFilled(true);
localXYLineAndShapeRenderer.setDrawOutlines(true);
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
// show item labels:
final XYItemRenderer renderer = plot.getRenderer();
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setBasePositiveItemLabelPosition(position);
final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator();
renderer.setSeriesItemLabelGenerator(0, generator);
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelGenerator(1, generator);
renderer.setSeriesItemLabelsVisible(1, true);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
return chart;
}
In the next graph, I draw with timeSeries, and the results is the same, showing the last day of previos month and first day of next month, I don not want to show this values.
The result that I need is like this image(a sample from chartJs):
How I can hide the zero and 31 from result of first top graph ?
long time later... ---- after a long time I make the desired graph myself ----- This code generates the right graph:
private JFreeChart TimeSeriesChartExample()
{
XYDataset dataset = createSampleMonthData();
// Create chart
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Time Series Chart Example",
"Date",
"Values",
dataset, true, true, false);
// Changes background color
XYPlot plot = (XYPlot)chart.getPlot();
plot.setBackgroundPaint(new Color(224, 224,235));
XYSplineRenderer renderer1 = new XYSplineRenderer();
renderer1.setSeriesPaint(0, Color.blue);
renderer1.setSeriesPaint(1, Color.green);
plot.setRenderer(renderer1);
plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3));
// show item labels:
XYItemRenderer renderer = plot.getRenderer();
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setBasePositiveItemLabelPosition(position);
final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator();
renderer.setSeriesItemLabelGenerator(0, generator);
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelGenerator(1, generator);
renderer.setSeriesItemLabelsVisible(1, true);
DateAxis xAxis = (DateAxis)plot.getDomainAxis();
xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy"));
ValueAxis domainAxis = plot.getDomainAxis();
domainAxis.setVerticalTickLabels(true);
return chart;
}
The solution is the follow, I put on the question body too:
private JFreeChart TimeSeriesChartExample()
{
XYDataset dataset = createSampleMonthData();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Time Series Chart Example",
"Date",
"Values",
dataset, true, true, false);
// Changes background color
XYPlot plot = (XYPlot)chart.getPlot();
plot.setBackgroundPaint(new Color(224, 224,235));
XYSplineRenderer renderer1 = new XYSplineRenderer();
renderer1.setSeriesPaint(0, Color.blue);
renderer1.setSeriesPaint(1, Color.green);
plot.setRenderer(renderer1);
plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3));
XYItemRenderer renderer = plot.getRenderer();
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setBasePositiveItemLabelPosition(position);
final StandardXYItemLabelGenerator generator = new StandardXYItemLabelGenerator();
renderer.setSeriesItemLabelGenerator(0, generator);
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelGenerator(1, generator);
renderer.setSeriesItemLabelsVisible(1, true);
DateAxis xAxis = (DateAxis)plot.getDomainAxis();
xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy"));
ValueAxis domainAxis = plot.getDomainAxis();
domainAxis.setVerticalTickLabels(true);
return chart;
}
This is the result:
Code as tested:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYSplineRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
/**
* @see https://stackoverflow.com/a/49909020/230513
*/
public class ChartTest {
private void display() {
JFrame f = new JFrame("ChartTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new ChartPanel(createTimeSeriesChartExample()){
@Override
public Dimension getPreferredSize() {
return new Dimension(1000, 400);
}
});
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private XYDataset createSampleMonthData() {
List<Integer> diario = new ArrayList<>(
Arrays.asList(20, 50, 120, 78, 37, 69, 145));
int dSize = diario.size();
int dPos = 0;
XYSeries serieD = new XYSeries("Diário");
XYSeries serieA = new XYSeries("Acumulado");
int acumulado = 0;
for (int i = 1; i < 31; i++) {
int valDay = diario.get(dPos++);
acumulado += valDay;
serieD.add(i, valDay);
serieA.add(i, acumulado);
if (dPos >= dSize) {
dPos = 0;
}
}
XYSeriesCollection result = new XYSeriesCollection(serieD);
result.addSeries(serieA);
return result;
}
private JFreeChart createTimeSeriesChartExample() {
XYDataset dataset = createSampleMonthData();
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Time Series Chart Example",
"Date",
"Values",
dataset, true, true, false);
// Changes background color
XYPlot plot = (XYPlot) chart.getPlot();
plot.setBackgroundPaint(new Color(224, 224, 235));
XYSplineRenderer renderer1 = new XYSplineRenderer();
renderer1.setSeriesPaint(0, Color.blue);
renderer1.setSeriesPaint(1, Color.green);
plot.setRenderer(renderer1);
plot.setAxisOffset(new RectangleInsets(3, 3, 3, 3));
XYItemRenderer renderer = plot.getRenderer();
ItemLabelPosition position = new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setBasePositiveItemLabelPosition(position);
final StandardXYItemLabelGenerator generator =
new StandardXYItemLabelGenerator();
renderer.setSeriesItemLabelGenerator(0, generator);
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelGenerator(1, generator);
renderer.setSeriesItemLabelsVisible(1, true);
DateAxis xAxis = (DateAxis) plot.getDomainAxis();
xAxis.setDateFormatOverride(new SimpleDateFormat("dd/MM/yy"));
ValueAxis domainAxis = plot.getDomainAxis();
domainAxis.setVerticalTickLabels(true);
return chart;
}
public static void main(String[] args) {
EventQueue.invokeLater(new ChartTest()::display);
}
}