业务需求
对百万级数据点进行绘制
Highcharts实现
使用Highcharts的Boost 模块实现该功能。Boost 模块由 WebGL 而不是默认的 SVG来实现图表的渲染,从而在几毫秒内呈现数十万个数据点。除了 WebGL 渲染之外,它还通过尽可能跳过数据的处理和检查来节省时间,但这可能导致在启用 Boost 模块后一些其他功能存在一些限制。
引入依赖项
javascript
import Highcharts from "highcharts";
import boost from "highcharts/modules/boost";
boost(Highcharts)
关键配置项
javascript
Highcharts.chart('container', {
boost: {
useGPUTranslations: true
},
});
完整代码
javascript
<template>
<div id="app">
<div id="container"></div>
</div>
</template>
<script>
import Highcharts from "highcharts";
import boost from "highcharts/modules/boost";
boost(Highcharts)
export default {
name: 'App',
mounted () {
this.getChart();
},
methods: {
getChart(){
var n = 1000000,
data = this.getData(n);// 获取数据
console.time('line');
Highcharts.chart('container', {
boost: {
useGPUTranslations: true
},
title: {
text: 'Highcharts drawing ' + n + ' points'
},
subtitle: {
text: 'Using the Boost module'
},
tooltip: {
valueDecimals: 2
},
series: [{
data: data,
lineWidth: 0.5
}]
});
console.timeEnd('line');
},
getData(n) {
var arr = [], i, a, b, c, spike;
for (i = 0; i < n; i = i + 1) {
if (i % 100 === 0) {
a = 2 * Math.random();
}
if (i % 1000 === 0) {
b = 2 * Math.random();
}
if (i % 10000 === 0) {
c = 2 * Math.random();
}
if (i % 50000 === 0) {
spike = 10;
} else {
spike = 0;
}
arr.push([i, 2 * Math.sin(i / 100) + a + b + c + spike + Math.random()]);
}
return arr;
},
}
}
</script>
<style>
.container{
width: 400px;
height: 400px;
}
</style>
效果图
数据渲染耗时:
ECharts实现
使用large属性启用大规模路径图的优化。是否开启大数据量优化,在数据图形特别多而出现卡顿时候可以开启。开启后配合 largeThreshold
在数据量大于指定阈值的时候对绘制进行优化。
缺点:优化后不能自定义设置单个数据项的样式。
引入依赖项
javascript
import * as echarts from 'echarts';
关键配置项
javascript
config = {
series: [
{
type: 'line',
data: this.ydata,
large: true
}
]
};
完整代码
javascript
<template>
<div id="app">
<div id="container"></div>
</div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'App',
data () {
return {
xdata:[],
ydata:[],
}
},
mounted () {
this.getEChart();
},
methods: {
getECharts(){
var n = 1000000,
this.getData(n);// 获取数据
console.time('echartsline');
let EChart = echarts.init(document.getElementById("EChart"));
let config = {
title: { text: 'Echarts drawing ' + n + ' points' },
tooltip: {
trigger: 'axis'
},
xAxis: {
silent: false,
data:this.xdata
},
yAxis: {},
series: [
{
type: 'line',
data: this.ydata,
large: true
}
],
};
EChart.setOption(config);
console.timeEnd('echartsline');
},
getData(n) {
var arr = [], i, a, b, c, spike;
for (i = 0; i < n; i = i + 1) {
if (i % 100 === 0) {
a = 2 * Math.random();
}
if (i % 1000 === 0) {
b = 2 * Math.random();
}
if (i % 10000 === 0) {
c = 2 * Math.random();
}
if (i % 50000 === 0) {
spike = 10;
} else {
spike = 0;
}
arr.push([i, 2 * Math.sin(i / 100) + a + b + c + spike + Math.random()]);
this.xdata.push(i);
this.ydata.push(arr[i][1]);
}
return arr;
},
}
}
</script>
<style>
.container{
width: 400px;
height: 400px;
}
</style>
效果图
渲染时间对比
1w | 20w | 50w | 100w | 200w | |
---|---|---|---|---|---|
Highcharts(折线图-1条) | 106.7 ms | 304.1 ms | 1004.7 ms | 1459.8 ms | 2359.1 ms(tooltip几乎无延迟) |
ECharts(折线图-1条) | 66.1 ms | 449.7 ms (tooltip卡顿) | 1200.7 ms(tooltip卡顿) | 2030.0 ms(tooltip卡顿) | 4529.7 ms(tooltip卡顿) |
Highcharts(折线图-5条) | 151.5 ms | 1082.6 ms | 3205.9 ms | 4734.0 ms | - |
ECharts(折线图-5条) | 109.4 ms | 1780.4 ms | 4800.5 ms | 10812.4 ms (25s) | - |
Highcharts(柱状图) | 142.1 ms | 480.5 ms | 1012.4 ms | 1521.5 ms | 5869.1 ms |
ECharts(柱状图) | 54.2 ms | 194.3 ms | 339.9 ms | 681.0 ms | 449.7 ms |
折线图:单条折线图时Highcharts与ECharts渲染时间在10w数据时基本持平,但ECharts在此数据量下tooltip仍然会出现卡顿的情况。10条折线时,15w数据量下,两者渲染时间基本持平,但ECharts在1.8w数据量时tooltip出现明显卡顿
柱状图:ECharts渲染时间远优于Highcharts
注
此demo使用版本:
json
{
"node": "^12.20.0",
"highcharts": "^11.2.0",
"echarts": "^5.0.0",
}