0

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();
        }
    }
}
Alex K
  • 22,315
  • 19
  • 108
  • 236
vivek agrawal
  • 41
  • 1
  • 11
  • This is not a feature of the chart itself. The enclosing `ChartPanel` handles this in `getToolTipText()`. Outside of a desktop context, you might look at a suitable label generator. – trashgod Dec 30 '18 at 16:29
  • Can we customize the chartPanel toolTiptext. When I am using chart customize I don't get the access of chart panel. Will it be possible you can give me some code example to customize the toolTiptext.. please note I am adding data from chart customizer class.. – vivek agrawal Dec 31 '18 at 09:15
  • Unless an enclosing `ChartPanel` calls `getToolTipText()`, your custom tooltip text will never be displayed. How are you displaying your report? Can you add a label generator like [this](https://stackoverflow.com/a/14459322/230513)? – trashgod Dec 31 '18 at 11:41
  • I designed the report with xyline charts(empty chart) and configured chart customizer. Chart customizer is given in my question. In customizer class I am not able to get the chartPanel object also not sure how to generate tool tip for the same. Since I have requirements to generate the SQL dynamically, get the data and set it to chart. Also I customize chart label series colors sequence... – vivek agrawal Dec 31 '18 at 14:48
  • I am deploying the report to jasper server and running the same report with custome input controls. So based on input controls sql query get generated. That is the reason I designed blank report with charts and deployed to jasper server. With custom data source and customizer I am rendering the chart which 100% dynamically generated. – vivek agrawal Dec 31 '18 at 15:53
  • In a server context, I usually go with a label generator, but you might also look an [image map](https://stackoverflow.com/q/21627587/230513). – trashgod Dec 31 '18 at 23:13
  • By adding following additional code I am able to get the tooltip, but this open the same chart in the new window. And chart displayed in jasper studio report viewer still does not shows the tool tips on mouse over. ChartFrame frame = new ChartFrame("First", chart); frame.pack(); frame.setVisible(true); – vivek agrawal Jan 02 '19 at 10:29
  • ChartFrame is a swing component you should not use this with jasper-reports (that is a tool to generate reports). If your export target format is html check this https://community.jaspersoft.com/blog/customizing-tooltips-jasperreports-html5-chart-components – Petter Friberg Jan 02 '19 at 14:04
  • Thank you @trashgod, with your help at least I noticed that on jasper server, chart is getting displayed as Image and it has the Map tag which actually have the tooltip information. Unfortunately, this Map tag is on updating when I add new data points from Customizer class. Can you please help me with this. I used ChartFrame just to understand where am I going wrong. So with Tooltip generator at least We know that tooltip is getting generated. How can we make sure that Map tag will get also getupdate with new Tooltip for new data points. – vivek agrawal Jan 02 '19 at 15:30
  • I'd do [this](https://stackoverflow.com/a/21670283/230513) or follow the HTML5 approach suggested above by @PetterFriberg – trashgod Jan 02 '19 at 17:00
  • The best solution for html is to use the latest HTML5 support of jasper-reports if you like to use the jfreechart component you should use HyperLink tooltip expression (hence add the series value that you like to have as tooltip) something like ` <![CDATA[$F{mySeries}]]> ` The ChartFrame is swing only class (installed application), that will not work when it's deployed on server. – Petter Friberg Jan 02 '19 at 17:15
  • Which IDE are you using to develop the jrxml with (Studio, iReport or notepad?) – Petter Friberg Jan 02 '19 at 17:19
  • @PetterFriberg Jasper Studio, I cant use since my data points and series get decided from xml file available on cloud. And since I have to deploy the report on jasper server I have been using customizer class. Based on your input, I guess I have other solution to generate the images of chart and keep it on server and using servlet API chart can get those images. But in this case i am not getting how am I going to handle the input control changes on jasper server page. Based on input control values the sql query filter (where condition get change..). – vivek agrawal Jan 02 '19 at 17:33
  • my requirement is 1. Report will be deployed on jasper server with some input controls like drop down and check boxes. 2. Based on input controls sql query will be updated to get the data from db. with this data charts will get displayed. 3. There is one more scenario where chart will get refresh every 5 min so that if there is any data change those will get reflected on chart. doesnt matter if input controls are changed or not. 4. Also import point is chart will be 100% customised using cloud xml file for series, colors, labels – vivek agrawal Jan 02 '19 at 17:35
  • So chart data does not depend on input controls? – Petter Friberg Jan 02 '19 at 18:41
  • chart data is dependent on input controls, Lets say I have one input control as Area, data will be fetched only for selected areas.. – vivek agrawal Jan 02 '19 at 19:00

1 Answers1

0

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);
vivek agrawal
  • 41
  • 1
  • 11