我用Echarts绘制出一条变色龙

1. 概述

需求设计:首先渲染的是一条线,该线能够实现在不同的时间区间范围展示不同的颜色(设定不同颜色是对应不同含义),使得这样以变色线形式代表的数据能够直观的显示其在一段时间周期中的各种状态变化(也就是数据可视化 :就是将相对抽象的的数据通过可视的、交互的方式进行展示,从而形象而又直观地表达出数据蕴含的信息和规律。简单来说,就是把复杂无序的数据用直观的图像展示出来,这样可以一下就能清晰的发现数据中潜藏的规律。)。

2. 技术

  • 使用的框架:Vue
  • 使用的组件库:Echarts
  • ECharts是百度开源的纯 Javascript 图表库,目前开源可以与highcharts相匹敌的一个图表库.支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)、雷达图(填充雷达图)、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图等12类图表,同时提供标题,详情气泡、图例、值域、数据区域、时间轴、工具箱等7个可交互组件,支持多图表、组件的联动和混搭展现。
  • Echarts思维导图

3. 实现

  • 如何实现一个Echarts图表?
  • 先绘制一个普通的折线图为例
arduino 复制代码
npm install echarts  // 下载文件
javascript 复制代码
import echarts from 'echarts'; 或者 const echarts = require("echarts");  //引入文件
ini 复制代码
// 折线DOM容器
 <div
     class="line"
     id="line"
     style="width:300px;height:200px;
 </div>
arduino 复制代码
// 实例化echarts对象
const line = document.getElementById("line");
const lineChart = echarts.init(line, null, {
          renderer: "svg",
        });
yaml 复制代码
// option 配置
option:{
   backgroundColor: '#5d87bb',
   grid: [
      {
         containLabel: true,
         left: '5%',
         top: '10%',
         right: '5%',
         backgroundColor: '#5d87bb',
      },
      {
         containLabel: true,
         left: '3%',
         top: '10%',
         right: '3%',
         backgroundColor: '#5d87bb',
      }
   ],
   title: {
      text: '鼠标按下拖拽试试'
   },
   dataZoom: [
      {
         show: false, // 为true 滚动条出现
         realtime: true,
         type: 'slider', // 有type这个属性,滚动条在最下面,也可以不行,写y:36,这表示距离顶端36px,一般就是在图上面。
         right: "3%",
         left: "3%",
         height: '10',
         xAxisIndex: [0],     //关联多个y轴
         moveHandleStyle: {
            color: "rgba(89, 202, 241,.5)",
         },
         moveHandleSize: "6",
         emphasis: {
            moveHandleStyle: {
               color: "rgba(89, 202, 241,.5)",
            }
         },
         textStyle: {
            color: "rgba(255,255,255,0)",
         },
         backgroundColor: 'rgba(255,255,255,.1)',
         borderColor: "rgba(255,255,255,0)",
         fillerColor: "rgba(0,0,0,0)",
         handleSize: "6",
         handleStyle: {
            color: "rgba(255,255,255,0)"
         },
         brushStyle: {
            color: "rgba(129, 243, 253)"
         },
         start: 0,
         end: 80,
      },
      {
         type: 'inside',
         xAxisIndex: [0],     //关联多个y轴
         zoomOnMouseWheel: false,  //滚轮是否触发缩放
         moveOnMouseMove: true
      }
   ],
   xAxis: [
      {
         type: 'time',
         triggerEvent: true,
         boundaryGap: false,
         axisLabel: {
            margin: 14,
            show: true,
            formatter: (v) => {
               let newDate = new Date(v);
               let newDate_h = newDate.getHours();
               let filter_ = data.filter((o) => {
                  let _date = new Date(o.time);
                  let _date_h = _date.getHours();
                  if (_date_h == newDate_h) return o;
               })[0];
               console.log(filter_, newDate_h)
               let rich_key = zh_en[filter_.weather];

               let grade = filter_.grade;
               let quality = filter_.quality;
               let str = `{${rich_key}| }\n{text|${grade}}\n{text2|${quality}}\n{h|${newDate_h}}`
               let sh = new Date().getHours();
               if (newDate_h == sh) {
                  str = `{${rich_key}| }\n{text|${grade}}\n{text2|${quality}}\n{sh|当前}`
               }
               return str;
            },
            rich: {
               ...rich_weathers,
               text: {
                  color: "#ffffff9a",
                  height: 30,
                  lineHeight: 30,
                  fontSize: 14,
                  align: 'center',
                  padding: [1, 3, 0, 0],
                  width: rich_img_w
               },
               text2: {
                  color: "#ffffff9a",
                  height: 20,
                  fontSize: 12,
                  align: 'center',
                  width: rich_img_w,
                  borderRadius: 4,
                  padding: [1.5, 3, 0, 0],
                  backgroundColor: '#ffffff1a'
               },
               h: {
                  color: "#ffffff9a",
                  height: 26,
                  fontSize: 12,
                  align: 'center',
                  width: rich_img_w,
                  borderRadius: 4,
                  padding: [1, 3, 0, 0],
               },
               sh: {
                  color: "#ffffff",
                  height: 26,
                  fontSize: 12,
                  align: 'center',
                  width: rich_img_w,
                  borderRadius: 4,
                  padding: [1, 3, 0, 0],
               }
            }
         },
         gridIndex: 0,
         axisLine: {
            show: false,
         },
         axisTick: {
            show: false,
         },
         splitLine: {
            show: false,
         },
      },
   ],
   yAxis: [
      {
         type: 'value',
         gridIndex: 0,
         axisLabel: {
            show: false
         },
         axisLine: {
            show: false,
         },
         axisTick: {
            show: false,
         },
         splitLine: {
            show: false,
         },
      },
   ],
   color: ['#00e529'],
   series: [
      {
         type: 'line',
         symbolSize: 10,
         symbol: 'image://' + lineSymbol,
         data: data.map((v) => {
            return [
               new Date(v.time),
               v.value
            ]
         }),
         yAxisIndex: 0,
         xAxisIndex: 0,
         smooth: true,
         label: {
            show: true,
            position: 'top',
            distance: 5,
            formatter: (v) => {
               return v.value[1] + '°'
            },
            color: "#fff",
            fontSize: 18,
            fontWeight: 600
         },
      },
   ]
};
scss 复制代码
// 渲染出一条折线
lineChart.setOption(option);

效果如下:

  • 铺垫结束 变色龙来了(先看由后端产生的实时数据渲染出的一条折线)

图一

图二

图三
这里图一实现的有两种变色线,上面一条平行X轴的线、下面一条Y轴值变化的线,共同点是对应时间区间映射的颜色保持一致,展示出其在一段时间周期中的各种状态变化以及值的变化。

4. 总结

yaml 复制代码
       // 背景数据配置
       markArea: {
                    silent: false,
                    itemStyle: {
                      color: this.isStatus(lineItem.severityStr).color,
                      opacity: "1",
                    },
                    data: [
                     // 背景矩形块 高度 (设置成有一定距离X轴的背景高度)
                      [
                        {
                          xAxis: lineItem.startTime,
                          yAxis: 130,  
                        },
                        {
                          xAxis: lineItem.startTime,
                          yAxis: 90, 
                        },
                      ],
                      // 背景矩形块 宽度
                      [
                        {
                          xAxis: lineItem.startTime,
                          yAxis: 90, 
                        },
                        {
                          xAxis: lineItem.endTime,
                          yAxis: 130, 
                        },
                      ],
                    ],
                  },
  • Y轴值变化、颜色变化的线怎么实现的呢? 其实是看似一条线、实则渲染了多条不同时间区间范围映射的线组合成一条线的效果,让多个线段相接连成一整条线。

5. 问题

  • 图三表格中渲染多条联动的线、数据量不那么庞大也出现滚动时间轴时卡顿问题?
相关推荐
Hockor1 小时前
用 Kimi K2 写前端是一种什么体验?还支持 Claude Code 接入?
前端
杨进军1 小时前
React 实现 useMemo
前端·react.js·前端框架
海底火旺1 小时前
浏览器渲染全过程解析
前端·javascript·浏览器
你听得到111 小时前
揭秘Flutter图片编辑器核心技术:从状态驱动架构到高保真图像处理
android·前端·flutter
驴肉板烧凤梨牛肉堡1 小时前
浏览器是否支持webp图像的判断
前端
Xi-Xu1 小时前
隆重介绍 Xget for Chrome:您的终极下载加速器
前端·网络·chrome·经验分享·github
摆烂为不摆烂1 小时前
😁深入JS(九): 简单了解Fetch使用
前端
杨进军1 小时前
React 实现多个节点 diff
前端·react.js·前端框架
用户40812812003811 小时前
拓展运算符和剩余参数
前端
再见了那维莱特1 小时前
6.29 drilling notes
前端