Search code examples
javachartsjfreechart

How to change from line chart to bar chart


I have this line chart and want to make it a bar chart, but I'm new to Java and am not knowing if it possible since the x-axis is TimeSeries. This is the code I have that visualizes the line chart:

public class Time {

private static Time INSTANCE;
public static boolean isInitialized = false;

private Marker marker;
private Long markerStart;
private Long markerEnd;

private XYPlot plot;

long last_lowerBound;
long last_upperBound;

@Inject
public Time() {

}

Composite comp;
TimeSeriesCollection dataset;
ChartPanel panel;
JFreeChart chart;
protected Point endPoint;

@PostConstruct
public void postConstruct(Composite parent) {
    comp = new Composite(parent, SWT.NONE | SWT.EMBEDDED);
    Frame frame = SWT_AWT.new_Frame(comp);

    JApplet rootContainer = new JApplet();

    TimeSeries series = new TimeSeries("Timeline");
    dataset = new TimeSeriesCollection();

    String plotTitle = "";
    String xaxis = "Time";
    String yaxis = "Docs";
    PlotOrientation orientation = PlotOrientation.VERTICAL;
    boolean show = false;
    boolean toolTips = true;
    boolean urls = false;

    chart = ChartFactory.createTimeSeriesChart(plotTitle, xaxis, yaxis, dataset, show, toolTips, urls );

    // get a reference to the plot for further customisation...
    plot = chart.getXYPlot();
    plot.setBackgroundPaint(Color.white);
    plot.setDomainGridlinePaint(Color.gray);
    plot.setRangeGridlinePaint(Color.gray);
    plot.setOutlinePaint(Color.white);
    plot.getRangeAxis().setLabel("");
    plot.getDomainAxis().setLabel("");
    ValueAxis y_axis = plot.getRangeAxis();     // Y
    ValueAxis x_axis = plot.getDomainAxis();    // X
    Font font = new Font("Veranda", Font.PLAIN, 12);
    y_axis.setTickLabelFont(font);
    x_axis.setTickLabelFont(font);
    x_axis.setTickLabelPaint(Color.black);
    y_axis.setTickLabelPaint(Color.black);
    plot.getDomainAxis().setAxisLineVisible(false);

    final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
    // renderer.setSeriesLinesVisible(0, false);
    renderer.setSeriesShapesVisible(0, false);
    plot.setRenderer(renderer);

Should I only update this line: chart = ChartFactory.createTimeSeriesChart(plotTitle, xaxis, yaxis, dataset, show, toolTips, urls ); or I should change it completely?

I tried changing this part like this but it doesn't show anything:

dataset = new TimeSeriesCollection();

    String plotTitle = "";
    String xaxis = "Time";
    String yaxis = "Docs";
    PlotOrientation orientation = PlotOrientation.VERTICAL;
    boolean show = false;
    boolean toolTips = true;
    boolean urls = false;

    chart = ChartFactory.createBarChart(plotTitle, xaxis, yaxis, (CategoryDataset) dataset, orientation, show, toolTips, urls);


    chart.setBackgroundPaint(null);
    chart.setBackgroundImageAlpha(0.0f);

    CategoryPlot plot = (CategoryPlot) chart.getPlot();
    plot.setRangeGridlinesVisible(false);
    plot.setDomainGridlinesVisible(false);
    plot.setOutlineVisible(false);
    plot.setRangeZeroBaselineVisible(false);
    plot.setDomainGridlinesVisible(false);
    plot.setBackgroundPaint(COLOR_INVISIBLE);
    plot.setBackgroundImageAlpha(0.0f);

    BarRenderer renderer = (BarRenderer) plot.getRenderer();
    renderer.setSeriesPaint(0, AttributeGuiTools.getColorForValueType(Ontology.NOMINAL));
    renderer.setBarPainter(new StandardBarPainter());
    renderer.setDrawBarOutline(true);
    renderer.setShadowVisible(false); } } 

Any help would be highly appreciated!


Solution

  • Given a suitable XYDataset, such as IntervalXYDataset, you can replace ChartFactory.createTimeSeriesChart() with ChartFactory.createXYBarChart(), which provides for an optional DateAxis. The example below uses the same dataset to create both charts.

    IntervalXYDataset dataset = createDataset();
    f.add(createPanel(ChartFactory.createXYBarChart("Data", "Time", true, "Value", dataset)));
    f.add(createPanel(ChartFactory.createTimeSeriesChart("Data", "Time", "Value", dataset)));
    

    image

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    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.DateTickMarkPosition;
    import org.jfree.chart.axis.DateTickUnit;
    import org.jfree.chart.axis.DateTickUnitType;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.data.time.TimeSeries;
    import org.jfree.data.time.TimeSeriesCollection;
    import org.jfree.data.time.Year;
    import org.jfree.data.xy.IntervalXYDataset;
    
    /**
     * @see https://stackoverflow.com/a/54362133/230513
     * @see https://stackoverflow.com/a/42612723/230513
     */
    public class Test {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Test()::display);
        }
    
        private void display() {
            JFrame f = new JFrame("Data");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLayout(new GridLayout(0, 1));
            IntervalXYDataset dataset = createDataset();
            f.add(createPanel(ChartFactory.createXYBarChart("Data", "Time", true, "Value", dataset)));
            f.add(createPanel(ChartFactory.createTimeSeriesChart("Data", "Time", "Value", dataset)));
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        private ChartPanel createPanel(JFreeChart chart) {
            final XYPlot plot = chart.getXYPlot();
            final DateAxis domainAxis = (DateAxis) plot.getDomainAxis();
            domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.YEAR, 1));
            domainAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
            domainAxis.setDateFormatOverride(new SimpleDateFormat("yyyy"));
            return new ChartPanel(chart) {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(500, 250);
                }
            };
        }
    
        private IntervalXYDataset createDataset() {
            TimeSeries series = new TimeSeries("Value");
            Calendar c = Calendar.getInstance();
            for (int i = 0; i < 7; i++) {
                series.add(new Year(c.getTime()), i + 1);
                c.add(Calendar.YEAR, 1);
            }
            return new TimeSeriesCollection(series);
        }
    }