Search code examples
javaswingjfreechart

How to update dataset in JFreeChart Bar Chart


I have got a JFrame, within this frame there is a JPanel, in a JPanel there is a JFreeChart (chart takes dataset from a method) and this chart is added to ChartPanel created in JPanel, then ChartPanel is added to JPanel. Also I have got JComboBox in JPanel, if I change option in that JComboBox an ActionListener updates value of dataset. Also method which return dataset, takes a string from JComboBox(data of dataset depends on JComboBox output). So if I change option in JComboBox I would want to update JFreeChart with new dataset and display it on screen. I know that I need to add code in that ActionListener but I don't what I should add there, is there any method which updates already created JFreeChart?

private class PanelChart extends JPanel { {
    this.setLayout(new BorderLayout());

    // Create Dataset
    //method GUIImplementation.GetDataForChart takes as an input value of combobox

    CategoryDataset dataset = GUIImplementation.GetDataForChart(comboBoxCrimeTypeChart.getSelectedItem().toString());


    //Create chart
    JFreeChart crimeNumberBarChart = ChartFactory.createBarChart(
        "Number of crimes by type", //Chart Title
        "Fallen within", // Category axis
        "Number of crimes", // Value axis
        dataset,
        PlotOrientation.VERTICAL,
        true,true,false
        );
    ChartPanel panelCrimeNumberBarChart = new ChartPanel(crimeNumberBarChart);
    this.add(panelCrimeNumberBarChart, BorderLayout.CENTER);

    PanelChartSouth panelChartSouth = new PanelChartSouth(); //there is a combobox
    this.add(panelChartSouth, BorderLayout.SOUTH);
}}

private class ChartButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == backChart) {
            SizeAndTitleSetter(0);
            SwapPanelChart(0);
        } else if(e.getSource() == comboBoxCrimeTypeChart) { //comboBoxCrimeTypeChart is a JComboBox from PanelChartSouth
            String crimeType = comboBoxCrimeTypeChart.getSelectedItem().toString();
            System.out.println(crimeType);
            dataset = GUIImplementation.GetDataForChart(crimeType); // dataset updated
        }
    }
}

So far I only managed to update somehow that chart by removing PanelChart from JFrame then create new PanelChart and add it to JFrame and use repaint and revalidate. It worked if I changed option in JComboBox once, after second change everything started to brake on screen, old chart didn't want to dissapear and new chart was under it and I could see it if I resized screen.


Solution

  • You can update an existing chart's dataset, as shown in these examples; when you update the model (dataset), the listening plot (view) will update itself accordingly; concrete implementations of CategoryDataset typically provide suitable mutators.

    DefaultCategoryDataset model = …
    …
    @Override
    public void actionPerformed(ActionEvent e) {
        model.setValue(…);
    }
    

    You can replace an existing chart's dataset using the relevant plot's setDataset() method.

    CategoryPlot plot = (CategoryPlot) chart.getPlot();
    …
    @Override
    public void actionPerformed(ActionEvent e) {
        plot.setDataset(…);
    }
    

    While it's technically possible to replace the enclosing view component, as suggested here, it's generally better to update or replace the model, as suggested here.