Objective: to generate the eckarts statistical picture directly according to options in the java background
The implementation principle of this paper: java calls Runtime.getRuntime().exec() to call phantomjs. Then phantomjs processes the echarts data, and finally generates the image.
Step 1: Download and install phantom JS
Download address: http://phantomjs.org/download.html
Configure environment variables after download
Configure the bin directory of the extracted folder to the environment variable Path
Verification results
Open the cmd window and enter the following
phantomjs --version
If version number appears, the configuration is successful.
Step 2: prepare to generate scripts related to pictures:
1. jquery-3.2.1.min.js
Download any version of jquery.js
2. echarts.min.js
Download address: https://echarts.baidu.com/download.html
3.echarts-convert.js
This script is the most important one, and the main logic code to generate the echart picture is in this script. (full source code is as follows)
(function () { var system = require('system'); var fs = require('fs'); var config = { // define the location of js files JQUERY: 'jquery-3.2.1.min.js', //ESL: 'esl.js', ECHARTS: 'echarts.min.js', // default container width and height DEFAULT_WIDTH: '600', DEFAULT_HEIGHT: '700' }, parseParams, render, pick, usage; usage = function () { console.log("\nUsage: phantomjs echarts-convert.js -options options -outfile filename -width width -height height" + "OR" + "Usage: phantomjs echarts-convert.js -infile URL -outfile filename -width width -height height\n"); }; pick = function () { var args = arguments, i, arg, length = args.length; for (i = 0; i < length; i += 1) { arg = args[i]; if (arg !== undefined && arg !== null && arg !== 'null' && arg != '0') { return arg; } } }; parseParams = function () { var map = {}, i, key; if (system.args.length < 2) { usage(); phantom.exit(); } for (i = 0; i < system.args.length; i += 1) { if (system.args[i].charAt(0) === '-') { key = system.args[i].substr(1, i.length); if (key === 'infile') { // get string from file // force translate the key from infile to options. key = 'options'; try { map[key] = fs.read(system.args[i + 1]).replace(/^\s+/, ''); } catch (e) { console.log('Error: cannot find file, ' + system.args[i + 1]); phantom.exit(); } } else { map[key] = system.args[i + 1].replace(/^\s+/, ''); } } } return map; }; render = function (params) { var page = require('webpage').create(), createChart; var bodyMale = config.SVG_MALE; page.onConsoleMessage = function (msg) { console.log(msg); }; page.onAlert = function (msg) { console.log(msg); }; createChart = function (inputOption, width, height,config) { var counter = 0; function decrementImgCounter() { counter -= 1; if (counter < 1) { console.log(messages.imagesLoaded); } } function loadScript(varStr, codeStr) { var script = $('<script>').attr('type', 'text/javascript'); script.html('var ' + varStr + ' = ' + codeStr); document.getElementsByTagName("head")[0].appendChild(script[0]); if (window[varStr] !== undefined) { console.log('Echarts.' + varStr + ' has been parsed'); } } function loadImages() { var images = $('image'), i, img; if (images.length > 0) { counter = images.length; for (i = 0; i < images.length; i += 1) { img = new Image(); img.onload = img.onerror = decrementImgCounter; img.src = images[i].getAttribute('href'); } } else { console.log('The images have been loaded'); } } // load opitons if (inputOption != 'undefined') { // parse the options loadScript('options', inputOption); // disable the animation options.animation = false; } // we render the image, so we need set background to white. $(document.body).css('backgroundColor', 'white'); var container = $("<div>").appendTo(document.body); container.attr('id', 'container'); container.css({ width: width, height: height }); // render the chart var myChart = echarts.init(container[0]); myChart.setOption(options); // load images loadImages(); return myChart.getDataURL(); }; // parse the params page.open("about:blank", function (status) { // inject the dependency js page.injectJs(config.ESL); page.injectJs(config.JQUERY); page.injectJs(config.ECHARTS); var width = pick(params.width, config.DEFAULT_WIDTH); var height = pick(params.height, config.DEFAULT_HEIGHT); // create the chart var base64 = page.evaluate(createChart, params.options, width, height,config); fs.write("base64.txt",base64); // define the clip-rectangle page.clipRect = { top: 0, left: 0, width: width, height: height }; // render the image page.render(params.outfile); console.log('render complete:' + params.outfile); // exit phantom.exit(); }); }; // get the args var params = parseParams(); // validate the params if (params.options === undefined || params.options.length === 0) { console.log("ERROR: No options or infile found."); usage(); phantom.exit(); } // set the default out file if (params.outfile === undefined) { var tmpDir = fs.workingDirectory + '/tmp'; // exists tmpDir and is it writable? if (!fs.exists(tmpDir)) { try { fs.makeDirectory(tmpDir); } catch (e) { console.log('ERROR: Cannot make tmp directory'); } } params.outfile = tmpDir + "/" + new Date().getTime() + ".png"; } // render the image render(params); }());
Note:
Step 3: back end preparation and code writing
1. Write common test options, mainly including line chart, bar chart and pie chart.
Pie chart sample options
{"title":{"text":"Channel map","subtext":"Channel statistics","x":"CENTER"},"toolbox": {"feature": {"saveAsImage": {"show": true,}}},"tooltip": {"show": true},"legend": {"data":["Direct access","Mail marketing","Alliance advertising","Video advertising","Search Engines"]}, "series":[{"name":"Access source","type":"pie","radius": '55%',"center": ['50%', '60%'],"data":[{"value":335, "name":"Direct access"},{"value":310, "name":"Mail marketing"},{"value":234, "name":"Alliance advertising"},{"value":135, "name":"Video advertising"},{"value":1548, "name":"Search Engines"}]}]}
Histogram sample options
{"title":{"text":"Sales chart","subtext":"Sales statistics","x":"left"},"toolbox": {"feature": {"saveAsImage": {"show": true,}}},"tooltip": {"show": true},"legend": {"data":['Sales volume']},"xAxis" : [{ "type" : "category","data" : ["shirt","Cardigan","Chiffon shirt","trousers","High-heeled shoes","Socks"]}],"yAxis" : [{"type" : "value"}],"series" : [{"name":"Sales volume","type":"bar","data":[5, 20, 40, 10, 10, 20]}]}
Line chart example options
{"title":{"text":"Resource growth","x":"left"},"toolbox":{"feature":{"saveAsImage":{"show":true,"title":"Save as picture","type":"png","lang":["Click save"]}},"show":true},"tooltip":{"trigger":"axis"},"legend":{"data":["ECS","Example","CPU","MEM"]},"xAxis":[{"boundaryGap":false,"type":"category","data":["2019-03-09","2019-03-02","2019-03-16"]}],"yAxis":[{"type":"value","position":"left","name":"ECS platform","axisLine":{"lineStyle":{"color":"#1E90FF"}}},{"type":"value","position":"left","name":"Container instance table","axisLine":{"lineStyle":{"color":"#8abee2 "}}]," series ": [{" name ":" ECS "," type ":" line line "," stack ":total", "data": [120132101101134, 90230210]}, {"name": "instance", "type":"line","stack":total "," data ": [2201821912323232323232323232323232323232323290330310]}, {" name ":" CPU "," type":"line","stack ":total", "data": [150232323220115414190330410]}, {"name": "MEM," MEM name ":" MEM, "mem name": [1502323232323232323220115411154190330410]},, {"name": "MEM name": "MEM" MEM, "total", "data": [15023232323232323232323232322011541"," type":"line","stack ":" total "," data ": [150232201154190330 410]}]}
2. Use the command of Java to call PhantomJS to generate the echarts picture (the full source code is as follows)
package com.seed.utils; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.util.UUID; public class EchartsTest { private static final String JSpath = "E:\\testProgram\\EchartsDemo\\tawa\\src\\main\\web\\js\\echarts-convert.js"; public static void main(String[] args) { String options = "{\"title\":{\"text\":\"Sales chart\",\"subtext\":\"Sales statistics\",\"x\":\"CENTER\"},\"toolbox\": {\"feature\": {\"saveAsImage\": {\"show\": true,}}},\"tooltip\": {\"show\": true},\"legend\": {\"data\":[\"Direct access\",\"Mail marketing\",\"Alliance advertising\",\"Video advertising\",\"Search Engines\"]}, \"series\":[{\"name\":\"Access source\",\"type\":\"pie\",\"radius\": '55%',\"center\": ['50%', '60%'],\"data\":[{\"value\":335, \"name\":\"Direct access\"},{\"value\":310, \"name\":\"Mail marketing\"},{\"value\":234, \"name\":\"Alliance advertising\"},{\"value\":135, \"name\":\"Video advertising\"},{\"value\":1548, \"name\":\"Search Engines\"}]}]}"; String picPath = generateEChart(options); } /* * main program */ public static String generateEChart(String options) { String dataPath = writeFile(options); String fileName= UUID.randomUUID().toString() + ".png"; String path = "D:/temp/Echart/" +fileName; try { File file = new File(path); //File path if (!file.exists()) { File dir = new File(file.getParent()); dir.mkdirs(); file.createNewFile(); } String cmd = "phantomjs " + JSpath + " -infile " + dataPath + " -outfile " + path;//Build command line Process process = Runtime.getRuntime().exec(cmd); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = input.readLine()) != null) { } input.close(); } catch (IOException e) { e.printStackTrace(); }finally{ } return path; } /* * * options Build file store */ public static String writeFile(String options) { String dataPath="D:\\chartData\\data"+ UUID.randomUUID().toString().substring(0, 8) +".json"; try { /* option Write text file for command execution*/ File writename = new File(dataPath); if (!writename.exists()) { File dir = new File(writename.getParent()); dir.mkdirs(); writename.createNewFile(); // } BufferedWriter out = new BufferedWriter(new FileWriter(writename)); out.write(options); out.flush(); // Push cache contents into file out.close(); // Close file last } catch (IOException e) { e.printStackTrace(); } return dataPath; } }
The generated image is output to the folder defined in the above code, and the result is shown in the figure below.