java后端生成highcharts图

概要

java1.8后端生成highcharts图
折线图样例
柱状图样例

技术细节

1.首先准备一份json格式绘图脚本(highcharts.json5),简单例举导出一个柱状图和一个折线图,代码如下

{
  temperature_product_chart: {
    credits: {
      enabled: false
    },
    title: {
      text: ''
    },
    subtitle: {
      text: ''
    },
    colors: [
      '#ad7f54',
      '#5ba057'
    ],
    chart: {
      animation: false
    },
    xAxis: {
      categories: [],
      tickColor: '#d3d3d3',
      lineColor: "#d3d3d3",
      tickPosition: 'inside',
      lineWidth: 2,
      tickWidth: 2,
      tickAmount: 10,
      title: {
        text: '年份',
        align: 'middle',
        style: {
          fontSize: "20px",
          fontFamily: '黑体',
          color: "#3f3f3f"
        }
      },
      labels: {
        //x轴刻度值
        y: 20,
        style: {
          fontSize: '18px',
          fontFamily: '宋体',
          color: '#030303'
        }
      }
    },
    yAxis: {
      tickColor: '#d3d3d3',
      lineColor: "#d3d3d3",
      floor: 0,
      gridLineWidth: 0,
      lineWidth: 2,
      tickWidth: 2,
      tickPosition: '',
      title: {
        align: 'middle',
        text: '月平均气温(℃)',
        style: {
          fontSize: '20px',
          fontFamily: '黑体',
          color: '#3f3f3f'
        }
      },
      labels: {
        style: {
          fontSize: '18px',
          fontFamily: '宋体',
          color: '#3f3f3f'
        }
      }
    },
    legend: {
      align: "center",
      verticalAlign: "top",
      backgroundColor: "rgba(0,0,0,0)",
      borderColor: '#ffffff',
      y: 30,
      itemStyle: {
        color: '#3f3f3f',
        fontWeight: 'bold',
        fontSize: '20px',
        borderWidth: 0
        // 设置边框宽度为0以移除边框
      }
    },
    plotOptions: {
      series: {
        borderWidth: 0,
        pointWidth: 20,
        marker: {
          enabled: false
        },
        label: {
          connectorAllowed: false
        }
      }
    },
    series: [
      {
        name: '安装,实施人员',
        data: [
          43934,
          52503,
          57177,
          69658,
          97031,
          119931,
          137133,
          154175
        ]
      },
      {
        name: '工人',
        data: [
          24916,
          24064,
          29742,
          29851,
          32490,
          30282,
          38121,
          40434
        ]
      }
    ]
  },
  rain_product_chart: {
    credits: {
      enabled: false
    },
    title: {
      text: ''
    },
    colors: [
      '#2265BB',
      '#5ba057'
    ],
    subtitle: {
      text: ''
    },
    chart: {
      animation: false
    },
    xAxis: {
      categories: [],
      tickColor: '#d3d3d3',
      lineColor: "#d3d3d3",
      tickPosition: 'inside',
      lineWidth: 2,
      tickWidth: 2,
      tickAmount: 10,
      title: {
        text: '年份',
        align: 'middle',
        style: {
          fontSize: "20px",
          fontFamily: '黑体',
          color: "#3f3f3f"
        }
      },
      labels: {
        //x轴刻度值
        y: 20,
        style: {
          fontSize: '18px',
          fontFamily: '宋体',
          color: '#030303'
        }
      }
    },
    yAxis: {
      tickColor: '#d3d3d3',
      lineColor: "#d3d3d3",
      floor: 0,
      gridLineWidth: 0,
      lineWidth: 2,
      tickWidth: 2,
      tickPosition: '',
      min: 0,
      title: {
        align: 'middle',
        text: '月降水量(毫米)',
        gridLgridLineWidth: 0,
        style: {
          fontSize: '20px',
          fontFamily: '黑体',
          color: '#3f3f3f'
        }
      },
      labels: {
        //y轴刻度值
        style: {
          fontSize: '18px',
          fontFamily: '宋体',
          color: '#3f3f3f'
        }
      }
    },
    legend: {
      align: "center",
      verticalAlign: "top",
      backgroundColor: "rgba(0,0,0,0)",
      borderColor: '#ffffff',
      y: 30,
      itemStyle: {
        color: '#3f3f3f',
        fontWeight: 'bold',
        fontSize: '20px',
        borderWidth: 0
        // 设置边框宽度为0以移除边框
      }
    },
    plotOptions: {
      column: {
        stacking: 'normal',
        pointWidth: 15,
        pointPadding: 0.5
      },
      series: {
        marker: {
          enabled: false
        },
        label: {
          connectorAllowed: false
        }
      }
    },
    series: [
      {
        type: 'column',
        name: '安装,实施人员',
        data: [
          43934,
          52503,
          57177,
          69658,
          97031,
          119931,
          137133,
          154175
        ]
      },
      {
        name: '工人',
        data: [
          24916,
          24064,
          29742,
          29851,
          32490,
          30282,
          38121,
          40434
        ]
      }
    ]
  }
}

2.下载zsdApp离线绘图服务包,解压后启动highcharts-png-renderer-master下的start.bat,
黑窗口显示端口号则为启动成功。

3.业务代码

@Test
    void testHighchart() {
        JSONObject query = new JSONObject();
        try {
            query = JSONObject.parseObject(IOUtils.toString(this.getClass().getClassLoader().getResourceAsStream("highcharts.json5"), "utf-8"));
        } catch (Exception e) {
            throw new BizException("500", "python参数导入失败");
        }

        JSONObject rainQuery = query.getJSONObject("rain_product_chart");
		//elementData数据集合
        List<StationElementData> elementData = this.mapper.list();
     
        //String[] yearArray =  elementData.stream().sorted(Comparator.comparing(StationElementData::getYear)).map(StationElementData::getYear).distinct().toArray(String[]::new);
        
        //降水
        JSONArray rainDatas = new JSONArray();
        List<StationElementData> rainChartData = new ArrayList<>();
        elementData.stream().collect(Collectors.groupingBy(StationElementData::getYear)).forEach((year, datas) -> {
            StationElementData stationElementData = new StationElementData();
            stationElementData.setYear(year);
            stationElementData.setDataValue(BigDecimalUtil.doubleOf(datas.stream().mapToDouble(StationElementData::getDataValue).average().orElse(0.0), 1));
            rainChartData.add(stationElementData);
        });
        
        rainChartData.sort(Comparator.comparing(StationElementData::getYear));
        String[] yearArray2 = rainChartData.stream().map(StationElementData::getYear).toArray(String[]::new);
        Double[] rainValue = rainChartData.stream().map(StationElementData::getDataValue).toArray(Double[]::new);
        Double[] climateRainValue = new Double[rainChartData.size()];
        double vClimateRain = rainChartData.stream().mapToDouble(StationElementData::getDataValue).average().orElse(0.0);
        Arrays.fill(climateRainValue, vClimateRain);//加常年值线
        rainDatas.add(new JSONObject().fluentPut("name", "历年值").fluentPut("data", rainValue).fluentPut("type", "column"));
        rainDatas.add(new JSONObject().fluentPut("name", "常年值").fluentPut("data", climateRainValue).fluentPut("lineWidth", 3));
        rainQuery.put("series", rainDatas);
        rainQuery.getJSONObject("xAxis").put("categories", yearArray2);
        rainQuery.getJSONObject("xAxis").put("tickInterval", Math.ceil(rainChartData.size() / 10));
        String filePathName = "D:\\rain_chart.png";
        sendPost("http://127.0.0.1:11942", JSONObject.toJSONString(rainQuery), filePathName);
    }
    

    /**
     * 发送请求绘制highcharts图
     *
     * @param url
     * @param param
     * @param filePathName
     * @return
     */
    private String sendPost(String url, String param, String filePathName) {
        OutputStream outputStream = null;
        InputStream inputStream = null;
        FileOutputStream fileOut = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            outputStream = conn.getOutputStream();
            outputStream.write(param.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
            // 获取URLConnection对象对应的输入流
            inputStream = conn.getInputStream();
            //控制流的大小为1k
            byte[] bs = new byte[10240];
            //读取到的长度
            int len = 0;
            //是否需要创建文件夹
            File file = new File(filePathName);
            // 如果文件目录不存在,则创建目录
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            //实例输出一个对象
            fileOut = new FileOutputStream(file);
            //循环判断,如果读取的个数b为空了,则is.read()方法返回-1,具体请参考InputStream的read();
            while ((len = inputStream.read(bs)) != -1) {
                //将对象写入到对应的文件中
                fileOut.write(bs, 0, len);
            }
        } catch (Exception e) {
            System.err.println("发送POST请求出现异常!" + e);
            e.printStackTrace();
        } finally {
            try {
                // 关闭输出流
                if (outputStream != null) {
                    outputStream.close();
                }
                // 关闭输入流
                if (inputStream != null) {
                    inputStream.close();
                }
                // 关闭文件输出流
                if (fileOut != null) {
                    fileOut.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值