Menu

How to make 2 pie charts using same legand

2012-04-03
2012-07-13
  • Shawn Quinn

    Shawn Quinn - 2012-04-03

    You can certainly add two pie charts that only have one legend rendered like so:

    final Chart chart = new Chart()
        .setChartTitleText("Two Pies");
    
    final Series series1 = chart.createSeries()
        .setName("Pie 1")
        .setType(Series.Type.PIE)
        .setPoints(new Point[]{
            new Point("Jane", 13).setColor("#20cbca"),
            new Point("John", 23).setColor("##0097dc"),
            new Point("Joe", 19).setColor("#738087")
        })
        .setPlotOptions(new PiePlotOptions()
            .setCenter(100, 80)
            .setSize(100)
            .setShowInLegend(true)
            .setDataLabels(new DataLabels()
                .setEnabled(false)
            )
        );
    
    final Series series2 = chart.createSeries()
        .setName("Pie 2")
        .setType(Series.Type.PIE)
        .setPoints(new Point[]{
            new Point("Jane", 13).setColor("#20cbca"),
            new Point("John", 23).setColor("##0097dc"),
            new Point("Joe", 19).setColor("#738087")
        })
        .setPlotOptions(new PiePlotOptions()
            .setCenter(280, 80)
            .setSize(100)
            .setShowInLegend(false)    // Toggle this if you want the legend items independent
            .setDataLabels(new DataLabels()
                .setEnabled(false)
            )
        );
    
    chart.addSeries(series1);
    chart.addSeries(series2);
    

    However, to then automatically hide the graphics of the second pie chart when a legend item of the first pie chart is clicked, you'd need to resort to native DOM manipulation as that jsfiddle chart is showing (at least until the core Highcharts API adds support for this). So, in GWT you could add methods like the following to the GWT Highcharts "Point" class:

    public boolean getNativeBoolean(String key) {
        return this.nativePoint != null && nativeGetBoolean(this.nativePoint, key);
    }
    
    public static native boolean nativeGetBoolean(JavaScriptObject point, String key) /*-{
        return point[key];
    }-*/;
    
    public void callSVGMethod(String svgElement, String method) {
        if(this.nativePoint != null) {
            nativeCallSVGMethod(this.nativePoint, svgElement, method);
        }
    }
    
    public static native void nativeCallSVGMethod(JavaScriptObject point, String svgElement, String method) /*-{
        point[svgElement][method]();
    }-*/;
    

    And then you could utilize those new methods by adding an event handler to your chart like so:

    chart.setPiePlotOptions(new PiePlotOptions()
        .setPointLegendItemClickEventHandler(new PointLegendItemClickEventHandler() {
            public boolean onClick(PointLegendItemClickEvent event) {
                Point point = series2.getPoints()[(int) event.getXAsLong()];
                if (event.getPoint().getNativeBoolean("visible")) {
                    point.callSVGMethod("graphic", "hide");
                } else {
                    point.callSVGMethod("graphic", "show");
                }
                return true;
            }
    
        })
    );
    

    Interesting use case! Hope that helps.

     
  • Shawn Quinn

    Shawn Quinn - 2012-04-04

    That change will be formally included in the 1.3.1 release, which I'm guessing will be released sometime later this month. If you need this function ahead of time though, all you'd need to do is replace the "Point.java" file in the jar file with the attached version.

    Also, in case it's useful to others, the following is an updated version of the "dual pie charts" example that would utilize this new "Point.getNativePoint()" method:

    private static native boolean nativeGetBoolean(JavaScriptObject point, String key) /*-{
        return point[key];
    }-*/;
    
    private static native void nativeCallSVGMethod(JavaScriptObject point, String svgElement, String method) /*-{
        point[svgElement][method]();
    }-*/;
    
    public Chart multiplePieCharts() {
    
        final Chart chart = new Chart()
            .setChartTitleText("Two Pies");
    
        final Series series1 = chart.createSeries()
            .setName("Pie 1")
            .setType(Series.Type.PIE)
            .setPoints(new Point[]{
                new Point("Jane", 13).setColor("#20cbca"),
                new Point("John", 23).setColor("##0097dc"),
                new Point("Joe", 19).setColor("#738087")
            })
            .setPlotOptions(new PiePlotOptions()
                .setCenter(100, 80)
                .setSize(100)
                .setShowInLegend(true)
                .setDataLabels(new DataLabels()
                    .setEnabled(false)
                )
            );
    
        final Series series2 = chart.createSeries()
            .setName("Pie 2")
            .setType(Series.Type.PIE)
            .setPoints(new Point[]{
                new Point("Jane", 13).setColor("#20cbca"),
                new Point("John", 23).setColor("##0097dc"),
                new Point("Joe", 19).setColor("#738087")
            })
            .setPlotOptions(new PiePlotOptions()
                .setCenter(280, 80)
                .setSize(100)
                .setShowInLegend(false)
                .setDataLabels(new DataLabels()
                    .setEnabled(false)
                )
            );
    
        chart.addSeries(series1);
        chart.addSeries(series2);
    
        chart.setPiePlotOptions(new PiePlotOptions()
            .setPointLegendItemClickEventHandler(new PointLegendItemClickEventHandler() {
                public boolean onClick(PointLegendItemClickEvent event) {
                    Point point = series2.getPoints()[(int) event.getXAsLong()];
                    if (nativeGetBoolean(event.getPoint().getNativePoint(), "visible")) {
                        nativeCallSVGMethod(point.getNativePoint(), "graphic", "hide");
                    } else {
                        nativeCallSVGMethod(point.getNativePoint(), "graphic", "show");
                    }
                    return true;
                }
    
            })
        );
    
        return chart;
    }
    
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.