Java自动化邮件中发送图表(三)之Highchart

小编 2026-06-10 阅读:1550 评论:0
一、Highchart (1)Highchart.js Highcharts 是一个用纯JavaScript编写的一个图表库。能够很简单便捷的在web网站或是web应用程序添加有交互性的图表。 (2)...

一、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-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 \'<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-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 \'<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 ();
		//导出柱状图png
		HighchartsExporter<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\"));
        //导出饼图png
		ChartOptions 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;
}

 

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表