SpringBoot集成echarts实现k线图功能

1.什么是echats?

ECharts是一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。 ECharts最初由百度团队开源,并于2018年初捐赠给Apache基金会,成为ASF孵化级项目。 2021年1月26日晚,Apache基金会官方宣布ECharts项目正式毕业。

2.代码工程

实验目的

实现股票日K线图

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>echarts</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

controller

访问根目录,跳转到首页

kotlin 复制代码
package com.et.echats.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class HelloWorldController {
    @RequestMapping("/")
    public String index()
    {
        return"index";
    }

}

index.html

常量data0 可以通过接口从后端获取,这里直接用静态数据

yaml 复制代码
<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>flask+echarts项目</title>
      <!-- 导入下载的 echarts.min.js -->
      <script src="../js/echarts.min.js"></script>
   </head>
   <body>
      <div id="main" style="width:100%;height:500px;"></div>

      <script type="text/javascript">
         // 基于准备好的dom,初始化echarts实例
         var myChart = echarts.init(document.getElementById('main'));

         // 自定义图表的宽高
         // var myChart=echarts.init(document.getElementById('main'),null,{width:500,height:400});

         // 跟随浏览器的宽度自适应图表大小
         // var myChart=echarts.init(document.getElementById('main'));
         // window.addEventListener('resize',function(){myChart.resize();});

         const upColor = "#ec0000";
         const upBorderColor = "#8A0000";
         const downColor = "#00da3c";
         const downBorderColor = "#008F28";

         // 拆分数据
         function splitData(rawData) {
            // 类型年份数据
            const categoryData = [];
            // 开盘价,收盘价,最低价,最高价
            const values = [];
            for (var i = 0; i < rawData.length; i++) {
               categoryData.push(rawData[i].splice(0, 1)[0]);
               values.push(rawData[i]);
            }
            return {
               categoryData: categoryData,
               values: values
            }
         };

         // 数据解释:时间,开盘价,收盘价,最低价,最高价
         const data0 = splitData([
            ['2023/1/24', 2320.26, 2320.26, 2287.3, 2362.94],
            ['2023/1/25', 2300, 2291.3, 2288.26, 2308.38],
            ['2023/1/28', 2295.35, 2346.5, 2295.35, 2346.92],
            ['2023/1/29', 2347.22, 2358.98, 2337.35, 2363.8],
            ['2023/1/30', 2360.75, 2382.48, 2347.89, 2383.76],
            ['2023/1/31', 2383.43, 2385.42, 2371.23, 2391.82],
            ['2023/2/1', 2377.41, 2419.02, 2369.57, 2421.15],
            ['2023/2/4', 2425.92, 2428.15, 2417.58, 2440.38],
            ['2023/2/5', 2411, 2433.13, 2403.3, 2437.42],
            ['2023/2/6', 2432.68, 2434.48, 2427.7, 2441.73],
            ['2023/2/7', 2430.69, 2418.53, 2394.22, 2433.89],
            ['2023/2/8', 2416.62, 2432.4, 2414.4, 2443.03],
            ['2023/2/18', 2441.91, 2421.56, 2415.43, 2444.8],
            ['2023/2/19', 2420.26, 2382.91, 2373.53, 2427.07],
            ['2023/2/20', 2383.49, 2397.18, 2370.61, 2397.94],
            ['2023/2/21', 2378.82, 2325.95, 2309.17, 2378.82],
            ['2023/2/22', 2322.94, 2314.16, 2308.76, 2330.88],
            ['2023/2/25', 2320.62, 2325.82, 2315.01, 2338.78],
            ['2023/2/26', 2313.74, 2293.34, 2289.89, 2340.71],
            ['2023/2/27', 2297.77, 2313.22, 2292.03, 2324.63],
            ['2023/2/28', 2322.32, 2365.59, 2308.92, 2366.16],
            ['2023/3/1', 2364.54, 2359.51, 2330.86, 2369.65],
            ['2023/3/4', 2332.08, 2273.4, 2259.25, 2333.54],
            ['2023/3/5', 2274.81, 2326.31, 2270.1, 2328.14],
            ['2023/3/6', 2333.61, 2347.18, 2321.6, 2351.44],
            ['2023/3/7', 2340.44, 2324.29, 2304.27, 2352.02],
            ['2023/3/8', 2326.42, 2318.61, 2314.59, 2333.67],
            ['2023/3/11', 2314.68, 2310.59, 2296.58, 2320.96],
            ['2023/3/12', 2309.16, 2286.6, 2264.83, 2333.29],
            ['2023/3/13', 2282.17, 2263.97, 2253.25, 2286.33],
            ['2023/3/14', 2255.77, 2270.28, 2253.31, 2276.22],
            ['2023/3/15', 2269.31, 2278.4, 2250, 2312.08],
            ['2023/3/18', 2267.29, 2240.02, 2239.21, 2276.05],
            ['2023/3/19', 2244.26, 2257.43, 2232.02, 2261.31],
            ['2023/3/20', 2257.74, 2317.37, 2257.42, 2317.86],
            ['2023/3/21', 2318.21, 2324.24, 2311.6, 2330.81],
            ['2023/3/22', 2321.4, 2328.28, 2314.97, 2332],
            ['2023/3/25', 2334.74, 2326.72, 2319.91, 2344.89],
            ['2023/3/26', 2318.58, 2297.67, 2281.12, 2319.99],
            ['2023/3/27', 2299.38, 2301.26, 2289, 2323.48],
            ['2023/3/28', 2273.55, 2236.3, 2232.91, 2273.55],
            ['2023/3/29', 2238.49, 2236.62, 2228.81, 2246.87],
            ['2023/4/1', 2229.46, 2234.4, 2227.31, 2243.95],
            ['2023/4/2', 2234.9, 2227.74, 2220.44, 2253.42],
            ['2023/4/3', 2232.69, 2225.29, 2217.25, 2241.34],
            ['2023/4/8', 2196.24, 2211.59, 2180.67, 2212.59],
            ['2023/4/9', 2215.47, 2225.77, 2215.47, 2234.73],
            ['2023/4/10', 2224.93, 2226.13, 2212.56, 2233.04],
            ['2023/4/11', 2236.98, 2219.55, 2217.26, 2242.48],
            ['2023/4/12', 2218.09, 2206.78, 2204.44, 2226.26],
            ['2023/4/15', 2199.91, 2181.94, 2177.39, 2204.99],
            ['2023/4/16', 2169.63, 2194.85, 2165.78, 2196.43],
            ['2023/4/17', 2195.03, 2193.8, 2178.47, 2197.51],
            ['2023/4/18', 2181.82, 2197.6, 2175.44, 2206.03],
            ['2023/4/19', 2201.12, 2244.64, 2200.58, 2250.11],
            ['2023/4/22', 2236.4, 2242.17, 2232.26, 2245.12],
            ['2023/4/23', 2242.62, 2184.54, 2182.81, 2242.62],
            ['2023/4/24', 2187.35, 2218.32, 2184.11, 2226.12],
            ['2023/4/25', 2213.19, 2199.31, 2191.85, 2224.63],
            ['2023/4/26', 2203.89, 2177.91, 2173.86, 2210.58],
            ['2023/5/2', 2170.78, 2174.12, 2161.14, 2179.65],
            ['2023/5/3', 2179.05, 2205.5, 2179.05, 2222.81],
            ['2023/5/6', 2212.5, 2231.17, 2212.5, 2236.07],
            ['2023/5/7', 2227.86, 2235.57, 2219.44, 2240.26],
            ['2023/5/8', 2242.39, 2246.3, 2235.42, 2255.21],
            ['2023/5/9', 2246.96, 2232.97, 2221.38, 2247.86],
            ['2023/5/10', 2228.82, 2246.83, 2225.81, 2247.67],
            ['2023/5/13', 2247.68, 2241.92, 2231.36, 2250.85],
            ['2023/5/14', 2238.9, 2217.01, 2205.87, 2239.93],
            ['2023/5/15', 2217.09, 2224.8, 2213.58, 2225.19],
            ['2023/5/16', 2221.34, 2251.81, 2210.77, 2252.87],
            ['2023/5/17', 2249.81, 2282.87, 2248.41, 2288.09],
            ['2023/5/20', 2286.33, 2299.99, 2281.9, 2309.39],
            ['2023/5/21', 2297.11, 2305.11, 2290.12, 2305.3],
            ['2023/5/22', 2303.75, 2302.4, 2292.43, 2314.18],
            ['2023/5/23', 2293.81, 2275.67, 2274.1, 2304.95],
            ['2023/5/24', 2281.45, 2288.53, 2270.25, 2292.59],
            ['2023/5/27', 2286.66, 2293.08, 2283.94, 2301.7],
            ['2023/5/28', 2293.4, 2321.32, 2281.47, 2322.1],
            ['2023/5/29', 2323.54, 2324.02, 2321.17, 2334.33],
            ['2023/5/30', 2316.25, 2317.75, 2310.49, 2325.72],
            ['2023/5/31', 2320.74, 2300.59, 2299.37, 2325.53],
            ['2023/6/3', 2300.21, 2299.25, 2294.11, 2313.43],
            ['2023/6/4', 2297.1, 2272.42, 2264.76, 2297.1],
            ['2023/6/5', 2270.71, 2270.93, 2260.87, 2276.86],
            ['2023/6/6', 2264.43, 2242.11, 2240.07, 2266.69],
            ['2023/6/7', 2242.26, 2210.9, 2205.07, 2250.63],
            ['2023/6/13', 2190.1, 2148.35, 2126.22, 2190.1]
         ]);

         // 计算MA(移动平均值)
         function calaculateMA(dayCount) {
            var result = [];
            for (var i = 0, len = data0.values.length; i < len; i++) {
               if (i < dayCount) {
                  result.push("-");
                  continue;
               }
               var sum = 0;
               for (var j = 0; j < dayCount; j++) {
                  sum += data0.values[i - j][1];
               }
               result.push(Math.round(sum/dayCount));
            }
            return result
         };

         // 指定图表的配置项和数据
         var option = {
            // 图表标题配置
            title: {
               text: 'K line graph'
            },
            // 提示框配置
            tooltip: {
               // 是否显示提示框
               show: true,
               // 触发类型,axis 移动到坐标轴就触发
               trigger: "axis",
               // 坐标轴上提示点设置
               axisPointer: {
                  type: "cross"
               }
            },
            // 图例配置
            legend: {
               data: ['day K', 'MA5', 'MA10', 'MA20', 'MA30']
            },
            // X 轴配置项
            xAxis: {
               type: "category",
               data: data0.categoryData,
               boundaryGap: false,
               axisLine: {
                  onZero: false
               },
               splitLine: {
                  show: true
               },
               min: "dataMin",
               max: "dataMax"
            },
            // y 轴配置项
            yAxis: {
               scale: true,
               splitArea: {
                  show: true
               }
            },
            dataZoom: [{
                  type: "inside",
                  start: 50,
                  end: 100
               },
               {
                  show: true,
                  type: "slider",
                  top: "90%",
                  start: 50,
                  end: 100
               }
            ],
            // 系列配置,根据不同图表有不同的配置
            series: [
               {
               name: "day K",
               // 图表类型
               type: 'candlestick',
               // 数据内容
               data: data0.values,
               // K 线图的图形样式
               itemStyle: {
                  // 阳线 图形的颜色
                  color: upColor,
                  // 阴线 图形的颜色。
                  color0: downColor,
                  // 阳线 图形的描边颜色
                  borderColor: upBorderColor,
                  // 阴线 图形的描边颜色
                  borderVolor0: downBorderColor
               },
               // 标记点配置
               markPoint: {
                  // 标注的文本
                  label: {
                     // 标签内容格式器,支持字符串模板和回调函数两种形式,字符串模板与回调函数返回的字符串均支持用 \n 换行。
                     // 参数 params 是 formatter 需要的单个数据集, value是传入的数据值。
                     formatter: function(param) {
                        return param != null ? Math.round(param.value) + "" : "";
                     }
                  },
                  // 标注的数据数组。每个数组项是一个对象
                  data: [
                     // 用 coord 属性指定数据在相应坐标系上的坐标位置
                     {
                        name: "Mark",
                        // 标注的坐标。坐标格式视系列的坐标系而定
                        coord: ['2023/5/31', 2300],
                        value: 2300,
                        itemStyle: {
                           color: 'rgb(41,60,85)'
                        }
                     },
                     // 特殊的标注类型,用于标注最大值最小值等
                     {
                        name: "highest value",
                        type: "max",
                        // 在使用 type 时有效,用于指定在哪个维度上指定最大值最小值。
                        valueDim: "highest",
                     },
                     {
                        name: 'lowest value',
                        type: 'min',
                        valueDim: 'lowest'
                     },
                     {
                        name: 'average value on close',
                        type: 'average',
                        valueDim: 'close'
                     }
                  ],
                  // 提示框浮层内容格式器,支持字符串模板和回调函数两种形式。
                  tooltip:{
                     // params 是 formatter 需要的数据集
                     formatter:function(param){
                        // name数据名,类目名,data传入的原始数据项
                        return param.name+"<br>"+(param.data.coord || "")
                     }
                  }
               },
               markLine:{
                  // 标线两端的标记类型,可以是一个数组分别指定两端,也可以是单个统一指定
                  symbol:['none','none'],
                  // 标线的数据数组。每个数组项可以是一个两个值的数组,分别表示线的起点和终点,每一项是一个对象
                  data:[
                     [
                        // 定义从最小值到最大值的线
                        {
                           name:"from lowest to highest",
                           type:"min",
                           valueDim:"lowest",
                           symbol:"circle",
                           symbolSize: 10,
                           label:{show:false},
                           emphasis:{label:{show:false}}
                        },
                        {
                           type:"max",
                           valueDim:"highest",
                           symbol:"circle",
                           symbolSize:10,
                           label:{show:false},
                           emphasis:{label:{show:false}}
                        },
                     ],
                     // 最小值水平线
                     {
                        name:"min line on close",
                        type:"min",
                        valueDim:"close"
                     },
                     // 最大值水平线
                     {
                        name:"max line on close",
                        type:"max",
                        valueDim:"close"
                     },
                  ],
               }
            },
            {
               name:"MA5",
               type:"line",
               data:calaculateMA(5),
               smooth:true,
               lineStyle:{opacity:0.5}
            },
            {
               name:"MA10",
               type:"line",
               data:calaculateMA(10),
               smooth:true,
               lineStyle:{opacity:0.5}
            },
            {
               name:"MA20",
               type:"line",
               data:calaculateMA(20),
               smooth:true,
               lineStyle:{opacity:0.5}
            },
            {
               name:"MA30",
               type:"line",
               data:calaculateMA(30),
               smooth:true,
               lineStyle:{opacity:0.5}
            },
            ]
         };
         //使用刚指定的配置项和数据显示图像
         myChart.setOption(option);
      </script>
   </body>
</html>

application.yaml

ini 复制代码
spring.thymeleaf.cache=false
spring.thymeleaf.suffix=.html

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

3.测试

4.引用

相关推荐
IT_陈寒1 分钟前
JavaScript性能飞跃:5个V8引擎优化技巧让你的代码提速300%
前端·人工智能·后端
Victor35614 分钟前
Redis(61)Redis的连接数上限是多少?
后端
Victor35618 分钟前
Redis(60) Redis的复制延迟如何优化?
后端
.格子衫.6 小时前
Spring Boot 原理篇
java·spring boot·后端
多云几多6 小时前
Yudao单体项目 springboot Admin安全验证开启
java·spring boot·spring·springbootadmin
摇滚侠8 小时前
Spring Boot 3零基础教程,Spring Intializer,笔记05
spring boot·笔记·spring
Jabes.yang8 小时前
Java求职面试实战:从Spring Boot到微服务架构的技术探讨
java·数据库·spring boot·微服务·面试·消息队列·互联网大厂
兮动人9 小时前
Spring Bean耗时分析工具
java·后端·spring·bean耗时分析工具
摇滚侠9 小时前
Spring Boot 3零基础教程,Demo小结,笔记04
java·spring boot·笔记
华洛9 小时前
公开一个AI产品的商业逻辑与设计方案——AI带来的涂色卡自由
前端·后端·产品