我用Echarts绘制出一条变色龙

2,858 阅读4分钟

line4.jpg

1. 概述

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

line6.jfif

2. 技术

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

line7.png

3. 实现

  • 如何实现一个Echarts图表?

image.png

  • 先绘制一个普通的折线图为例
npm install echarts  // 下载文件
import echarts from 'echarts'; 或者 const echarts = require("echarts");  //引入文件
// 折线DOM容器
 <div
     class="line"
     id="line"
     style="width:300px;height:200px;
 </div>
// 实例化echarts对象
const line = document.getElementById("line");
const lineChart = echarts.init(line, null, {
          renderer: "svg",
        });
// 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
         },
      },
   ]
};

// 渲染出一条折线
lineChart.setOption(option);

效果如下: image.png

  • 铺垫结束 变色龙来了(先看由后端产生的实时数据绘制出的折线类型图表)

line01.png

图一

line2.png

图二

line8.jpg

图三

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

4. 总结

       // 背景数据配置
       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. 问题

  • 图三表格中渲染多条联动的线、数据量不那么庞大也出现滚动时间轴时卡顿问题?