Search code examples
jfreechart

JFreeChart XYLineAndShapeRenderer show unwanted vales outside range start and finish


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;
}

enter image description here

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. enter image description here

The result that I need is like this image(a sample from chartJs): enter image description here

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;
}

This is the resultando graph: enter image description here


Solution

  • 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:

    enter image description here

    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);
        }
    }