(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-basic
ChartOptions chartOptions = factory.createChartOptions ();
chartOptions.getChart ().setDefaultSeriesType (SeriesType.column)
.setWidth (800).setHeight (400).setMarginLeft (70).setMarginTop (80);
// titles
chartOptions.getTitle ().setText ("Monthly Average Rainfall");
chartOptions.getSubtitle ().setText ("Source: WorldClimate.com");
// xAxis
chartOptions.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");
// yAxis
chartOptions.getYAxis ().setMin (0).getTitle ().setText ("Rainfall (mm)");
// Legend
chartOptions.getLegend ().setLayout ("vertical").setAlign ("left")
.setVerticalAlign ("top").setX (100).setY (70);
// PlotOptions
chartOptions.getPlotOptions ().getColumn ().setBorderWidth (0);
// Several series
addSeries (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-basic
ChartOptions chartOptions = factory.createChartOptions ();
chartOptions.getChart ().setWidth (800).setHeight (600).setMarginLeft (70)
.setMarginTop (80);
// title
chartOptions.getTitle ().setText (
"Browser market shares at a specific website, 2010");
// plotOptions
chartOptions
.getPlotOptions ()
.getPie ()
.setAllowPointSelect (true)
.getDataLabels ()
.setEnabled (true)
.setColor ("#000000")
.setFormatter (
"function() {return ''+ this.point.name +': '+ 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-time
ChartOptions chartOptions = factory.createChartOptions ();
chartOptions.getChart ().setWidth (800).setHeight (600)
.setDefaultSeriesType (SeriesType.spline).setMarginLeft (70)
.setMarginTop (80);
// titles
chartOptions.getTitle ().setText (
"Snow depth in the Vikjafjellet mountain, Norway");
chartOptions.getSubtitle ().setText (
"An example of irregular time data in Highcharts JS");
// axis
chartOptions.getXAxis ().setType ("datetime").getDateTimeLabelFormats ()
.set (TimeUnit.month, "%e. %b").set (TimeUnit.year, "%b");
chartOptions.getYAxis ().setMin (0).getTitle ().setText ("Snow depth (m)");
// plotOptions
chartOptions
.getPlotOptions ()
.getPie ()
.setAllowPointSelect (true)
.getDataLabels ()
.setEnabled (true)
.setColor ("#000000")
.setFormatter (
"function() {return ''+ this.point.name +': '+ 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 ();
//导出柱状图png
HighchartsExporter 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"));
//导出饼图png
ChartOptions chartOptions3 = highchartsSamples.createTimeDataWithIrregularIntervals ();
final HighchartsExporter jpegExporter = ExportType.jpeg.createExporter ();
jpegExporter.export (chartOptions3, null, new File (exportDirectory, "time-data-with-irregular-intervals.jpeg"));
//柱状图json字符串
String chartOption = highchartsSamples.createJsonColumnBasic ();
HighchartsExporter 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 {
public HighchartsExporter(ExportType type, SVGRendererInternal internalRenderer) {
this.type = type;
this.renderer =
new SVGStreamRenderer (new SVGRenderer (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 renderer;
private final ExportType type;
}