Search code examples
javajasper-reportsjfreechart

JFreeChart: custom chart with tooltip on mouseover


I have requirement to show a XyLineChart with adding data dynamically. I have used the chart Customizer to read data from db with some additional logic and adding that to chart. But I am not able to create tool tip on mouse over for each data points on chart. following is my code for Customizer.

What is the correct way to create Tool tip on Mouse over?

public class MyChartCustomizer extends JRAbstractChartCustomizer{

    @Override
    public void customize(JFreeChart chart, JRChart jrChart) {
        XyPlot plot= chart.getXyPlot;
        XYSeriesCollection ds =  (XYSeriesCollection) plot.getDataset();
        XYSeries x1 = new XYSeries("C 1", true, true);

        x1.add(10,20);
        XYBarRenderer ren = (XYBarRenderer) plot.getRenderer();
        plot.setRenderer(ren);
        ren.setSeriesToolTipGenerator(0, new XYToolTipGenerator() {
            @Override
            public String generateToolTip(XYDataset arg0, int arg1, int arg2) {
                return "C 1";
            }
            });
            ren.setToolTipGenerator(new XYToolTipGenerator() {
                @Override
                public String generateToolTip(XYDataset arg0, int arg1, int arg2)                   {
                    return "C 1";
                }
            });
            chart.fireChartChanged();
        }
    }
}

Solution

  • Thank you, Petter and Trashgod helping me out to find the solution for this issue. The actual issue is, if we add the new data using customizer then the new data point get display on the graph but respected tool tip does not get generated and the map used for tooltip will not be updated on html code. Since I have to use jasper server as per requirement I implemented following work around other way will be simply generate chart image with map using jfreechart API and display on the jsp page(no need for report design....).. Following is the way I Implemented this.

    I used the following code to generate the same chart which jasperserver/jasper studio create the chart. this gives me same chart which internally get created and I create the map for tooltips and passing it as parameter to browser and using javascript function inserting the new map html code with the chart image.

                XYSeriesCollection xyDataSet = new XYSeriesCollection();
    
            JFreeChart chart = ChartFactory.createXYLineChart(
                    cur_chart.getTitle(),
                    cur_chart.getxLabel(), cur_chart.getyLabel(),
                    xyDataSet,
                    PlotOrientation.VERTICAL,
                    true,
                    true,
                    false);
    
            String chartId = null;
            for ( Object  tt :  chart.getSubtitles()){
                if (tt instanceof TextTitle){
                    chartId= ((TextTitle) tt).getText();
                }
            }
    
            XYPlot plot = chart.getXYPlot();
    
    
        //following code to set font size and color is required so that same chart with matching tooltip pixels can we generated. 
            LegendItemCollection legends =  plot.getLegendItems();
    
    
            List<JRSeriesColor> colors = new ArrayList<JRSeriesColor>();
    
            System.out.println("Customizer: "+ chartId);
    
            NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();
            NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
            xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
            yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
    
            Color trans = new Color(0xFF, 0xFF, 0xFF, 0);
            chart.setBackgroundPaint(trans);
            plot .setBackgroundPaint(trans);
            chart.getLegend().setBackgroundPaint(trans);
    
            chart.setTitle(cur_chart.getTitle());
    
            Font font3 = new Font("Dialog", Font.PLAIN, 10); 
            plot.getDomainAxis().setLabelFont(font3);
            plot.getRangeAxis().setLabelFont(font3);
            plot.getDomainAxis().setLabelPaint(Color.BLACK);
            plot.getRangeAxis().setLabelPaint(Color.BLACK);
    
        //some more code to add real time data to XyDataset, 
    
    
        ToolTipTagFragmentGenerator tooltipConstructor = new ToolTipTagFragmentGenerator() {
                public String generateToolTipFragment(String arg0) {
                    String toolTip = " title = \"" + arg0.replace("\"", "") + "\"";
                    return (toolTip);
                }
            };
    
            URLTagFragmentGenerator urlConstructor = new URLTagFragmentGenerator() {
                public String generateURLFragment(String arg0) {
                    String address = " href=\"ControllerAddress\\methodName?"
                        + arg0.replace("\"", "") + "\"";
                    return (address);
                }
            };
    
    
    
            ChartRenderingInfo info = new ChartRenderingInfo(
                    new StandardEntityCollection());
           // BufferedImage bi  chart.createBufferedImage(272, 178, info); 
            TextTitle tt =  new TextTitle("chart1");
            tt.setFont(font3);
            chart.addSubtitle(tt);
            ChartUtilities.saveChartAsPNG(new File("/tmp/test.png"), chart, 500, 250, info);
        String map = ChartUtilities.getImageMap(cur_chart.getName(), info, tooltipConstructor, urlConstructor);