The implementation of java + phantom JS generates the images of eckarts in the background (full source code)

Keywords: Java JQuery Javascript JSON

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.

Posted by Zag0r on Wed, 16 Oct 2019 09:51:22 -0700