一、Highchart
(1)Highchart.js
Highcharts 是一个用纯JavaScript编写的一个图表库。能够很简单便捷的在web网站或是web应用程序添加有交互性的图表。
(2)highcharts-serverside-export
Highcharts Serverside Export框架(HSE)的主要目标是为Highcharts提供包含图像生成功能的Java API。
与Highcharts模型对应的Java API (与Highcharts模型层次结构和属性保持兼容),基于Rhino-Apache Batik的渲染器:java ChartOptions ==> Rhino ==> Highcharts ==> SVG ==> image(png,JPEG等等),
二、实例
(1)柱状图
public ChartOptions createColumnBasic () {// http://highcharts.com/demo/column-basicChartOptions chartOptions = factory.createChartOptions ();chartOptions.getChart ().setDefaultSeriesType (SeriesType.column).setWidth (800).setHeight (400).setMarginLeft (70).setMarginTop (80);// titleschartOptions.getTitle ().setText ("Monthly Average Rainfall");chartOptions.getSubtitle ().setText ("Source: WorldClimate.com");// xAxischartOptions.getXAxis ().getCategories ().pushString ("Jan").pushString ("Feb").pushString ("Mar").pushString ("Apr").pushString ("May").pushString ("Jun").pushString ("Jul").pushString ("Aug").pushString ("Sep").pushString ("Oct").pushString ("Nov").pushString ("Dec");// yAxischartOptions.getYAxis ().setMin (0).getTitle ().setText ("Rainfall (mm)");// LegendchartOptions.getLegend ().setLayout ("vertical").setAlign ("left").setVerticalAlign ("top").setX (100).setY (70);// PlotOptionschartOptions.getPlotOptions ().getColumn ().setBorderWidth (0);// Several seriesaddSeries (chartOptions, "Tokyo", new double[] { 49.9, 71.5, 106.4, 129.2,144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4 });addSeries (chartOptions, "New York", new double[] { 83.6, 78.8, 98.5, 93.4,106.0, 84.5, 105.0, 104.3, 91.2, 83.5, 106.6, 92.3 });addSeries (chartOptions, "London", new double[] { 48.9, 38.8, 39.3, 41.4,47.0, 48.3, 59.0, 59.6, 52.4, 65.2, 59.3, 51.2 });addSeries (chartOptions, "Berlin", new double[] { 42.4, 33.2, 34.5, 39.7,52.6, 75.5, 57.4, 60.4, 47.6, 39.1, 46.8, 51.1 });return chartOptions;}
(2)饼图
public ChartOptions createPieChart () {// http://highcharts.com/demo/pie-basicChartOptions chartOptions = factory.createChartOptions ();chartOptions.getChart ().setWidth (800).setHeight (600).setMarginLeft (70).setMarginTop (80);// titlechartOptions.getTitle ().setText ("Browser market shares at a specific website, 2010");// plotOptionschartOptions.getPlotOptions ().getPie ().setAllowPointSelect (true).getDataLabels ().setEnabled (true).setColor ("#000000").setFormatter ("function() {return '<b>'+ this.point.name +'</b>: '+ this.y +' %';}");Series newSeries = factory.createSeries ().setName ("Browser share").setType ("pie");chartOptions.getSeries ().pushElement (newSeries);newSeries.getData ().pushElement (factory.createPoint ().setName ("Firefox").setY (45)).pushElement (factory.createPoint ().setName ("IE").setY (26.8)).pushElement (factory.createPoint ().setName ("Chrome").setY (12.8).setSliced (true).setSelected (true)).pushElement (factory.createPoint ().setName ("Safari").setY (8.5)).pushElement (factory.createPoint ().setName ("Opera").setY (6.2)).pushElement (factory.createPoint ().setName ("Others").setY (0.7));return chartOptions;}
(3)折线图
public ChartOptions createTimeDataWithIrregularIntervals () {// http://highcharts.com/demo/spline-irregular-timeChartOptions chartOptions = factory.createChartOptions ();chartOptions.getChart ().setWidth (800).setHeight (600).setDefaultSeriesType (SeriesType.spline).setMarginLeft (70).setMarginTop (80);// titleschartOptions.getTitle ().setText ("Snow depth in the Vikjafjellet mountain, Norway");chartOptions.getSubtitle ().setText ("An example of irregular time data in Highcharts JS");// axischartOptions.getXAxis ().setType ("datetime").getDateTimeLabelFormats ().set (TimeUnit.month, "%e. %b").set (TimeUnit.year, "%b");chartOptions.getYAxis ().setMin (0).getTitle ().setText ("Snow depth (m)");// plotOptionschartOptions.getPlotOptions ().getPie ().setAllowPointSelect (true).getDataLabels ().setEnabled (true).setColor ("#000000").setFormatter ("function() {return '<b>'+ this.point.name +'</b>: '+ this.y +' %';}");Series newSeries = factory.createSeries ().setName ("Winter 2007-2008");chartOptions.getSeries ().pushElement (newSeries);newSeries.getData ().pushElement (factory.createPoint ().setX (getDateUTC (1970, 9, 27)).setY (0)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 10, 10)).setY (0.6)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 10, 18)).setY (0.7)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 11, 2)).setY (0.8)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 11, 9)).setY (0.6)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 11, 16)).setY (0.6)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 11, 28)).setY (0.67)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 0, 1)).setY (0.81)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 0, 8)).setY (0.78)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 0, 12)).setY (0.98)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 0, 27)).setY (1.84)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 10)).setY (1.8)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 18)).setY (1.8)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 24)).setY (1.92)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 4)).setY (2.49)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 11)).setY (2.79)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 15)).setY (2.73)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 25)).setY (2.61)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 2)).setY (2.76)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 6)).setY (2.82)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 13)).setY (2.8)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 4, 3)).setY (2.1)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 4, 26)).setY (1.1)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 5, 9)).setY (0.25)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 5, 12)).setY (0));newSeries = factory.createSeries ().setName ("Winter 2008-2009");chartOptions.getSeries ().pushElement (newSeries);newSeries.getData ().pushElement (factory.createPoint ().setX (getDateUTC (1970, 9, 18)).setY (0)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 9, 26)).setY (0.2)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 11, 1)).setY (0.47)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 11, 11)).setY (0.55)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 11, 25)).setY (1.38)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 0, 8)).setY (1.38)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 0, 15)).setY (1.38)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 1)).setY (1.38)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 8)).setY (1.48)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 21)).setY (1.5)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 12)).setY (1.89)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 25)).setY (2.0)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 4)).setY (1.94)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 9)).setY (1.91)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 13)).setY (1.75)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 19)).setY (1.6)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 4, 25)).setY (0.6)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 4, 31)).setY (0.35)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 5, 7)).setY (0));newSeries = factory.createSeries ().setName ("Winter 2009-2010");chartOptions.getSeries ().pushElement (newSeries);newSeries.getData ().pushElement (factory.createPoint ().setX (getDateUTC (1970, 9, 9)).setY (0)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 9, 14)).setY (0.15)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 10, 28)).setY (0.35)).pushElement (factory.createPoint ().setX (getDateUTC (1970, 11, 12)).setY (0.46)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 0, 1)).setY (0.59)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 0, 24)).setY (0.58)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 1)).setY (0.62)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 7)).setY (0.65)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 1, 23)).setY (0.77)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 8)).setY (0.77)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 14)).setY (0.79)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 2, 24)).setY (0.86)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 4)).setY (0.8)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 18)).setY (0.94)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 3, 24)).setY (0.9)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 4, 16)).setY (0.39)).pushElement (factory.createPoint ().setX (getDateUTC (1971, 4, 21)).setY (0));return chartOptions;}
三、图片导出
(1)测试例子
package examples;import java.io.File;import org.one2team.highcharts.server.export.ExportType;
import org.one2team.highcharts.server.export.HighchartsExporter;
import org.one2team.highcharts.shared.ChartOptions;
import org.one2team.highcharts.shared.Jsonify;public class SimpleExport {public static void main (String[] args) {//图片导出目录File exportDirectory = new File ("./b");if (!exportDirectory.exists()) {exportDirectory.mkdirs();}final SamplesFactory highchartsSamples = SamplesFactory.getSingleton ();// 创建柱状图ChartOptions chartOptions1 = highchartsSamples.createColumnBasic ();//导出柱状图pngHighchartsExporter<ChartOptions> pngExporter = ExportType.png.createExporter ();pngExporter.export (chartOptions1, null, new File (exportDirectory, "column-basic.png"));//创建饼图ChartOptions chartOptions2 = highchartsSamples.createPieChart ();pngExporter.export (chartOptions2, null, new File (exportDirectory, "pie-chart.png"));//导出饼图pngChartOptions chartOptions3 = highchartsSamples.createTimeDataWithIrregularIntervals ();final HighchartsExporter<ChartOptions> jpegExporter = ExportType.jpeg.createExporter ();jpegExporter.export (chartOptions3, null, new File (exportDirectory, "time-data-with-irregular-intervals.jpeg"));//柱状图json字符串String chartOption = highchartsSamples.createJsonColumnBasic ();HighchartsExporter<String> pngFromJsonExporter = ExportType.png.createJsonExporter ();pngFromJsonExporter.export (chartOption, null, new File (exportDirectory, "column-basic-from-json.png"));//柱状图Jsonify对象,JSMHighchartsFactory的ChartOption实现Jsonify接口 Jsonify jsonify = (Jsonify) highchartsSamples.createColumnBasic ();String json = jsonify.toJson ();System.out.println("json "+json);pngFromJsonExporter.export (json, null, new File (exportDirectory, "column-basic-from-jsonified-java.png"));}}
(2)API缺点没有直接转成字节数组的方法
package org.one2team.highcharts.server.export;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;import org.apache.commons.io.IOUtils;
import org.one2team.highcharts.server.export.util.SVGRendererInternal;public class HighchartsExporter<T> {public HighchartsExporter(ExportType type, SVGRendererInternal<T> internalRenderer) {this.type = type;this.renderer = new SVGStreamRenderer<T> (new SVGRenderer<T> (internalRenderer),type.getTranscoder ());}//新增的导出字节数组方法public byte[] export (T chartOptions,T globalOptions) {ByteArrayOutputStream fos = null;try {fos=new ByteArrayOutputStream();renderer.setChartOptions (chartOptions).setGlobalOptions (globalOptions).setOutputStream (fos).render ();return fos.toByteArray();} catch (Exception e) {e.printStackTrace ();throw (new RuntimeException (e));} finally {if (fos != null)IOUtils.closeQuietly (fos);}}private final SVGStreamRenderer<T> renderer;private final ExportType type;
}