要可视化展示设备数据,而这个设备数据非常多,一小时就能产生上百万条数据,传过来的json文件都有几百兆大小;
我使用的vue3 vite echarts
chrome单标签4g内存爆了
使用原生html js echarts,然后直接引入这个json文件到渲染出来要20秒左右,但是能够展示
不能取平均值等,降低采样来减小吗?
我们分了一个降采样的查询和不做任何处理的查询,这个就是那个不做处理的
原生js
<div id="main" style="width: 600px;height:400px;"></div>
<!-- <div id="tester" style="width:600px;height:250px;"></div> -->
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<!-- <script src="./plotly-2.32.0.min.js" charset="utf-8"></script> -->
<script src="./response.js"></script>
<script>
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;
const xx = data.data.dates
const yy = data.data.directionx
option = {
xAxis: { type: 'category', data: xx },
yAxis: { type: 'value' },
series: [{ data: yy, type: 'line', sampling: 'lttb' }]
};
option && myChart.setOption(option);
</script>
部分数据:
{
"code": 0,
"msg": null,
"data": {
"directionx": [6.492834006493665E-4, 6.509656666877379E-4,],
"directiony": [5.452070495968005E-4, 5.45381096391632E-4,],
"dates": ["2024-07-11 13:43:00", "2024-07-11 13:44:00",],
"directionz": [5.630059477387331E-4, 5.6277585267251E-4,],
"info": ["[2,+)", "[1.6,2)", "[1.2,1.6)"]
},
"ok": true
}
5个小时的数据:123云盘
vue方面我使用的vue-echarts
希望各位多给点建议或者评论,各个方面都可以
目前有的想法是:
1.iframe (尝试中)
2.流式处理,一次处理一部分,这样应该不会爆内存(没想好具体怎么实现)
3.流式传输,大范围时只有部分数据(反正像素点都被画满了,少了数据看起来也是一样的)当范围缩小时,再进一步拉取数据,类似与地图瓦片那种
尝试使用iframe,把数据传过去(想省去登录),但是加载不出来,但是如果只使用少量的条数就可以,很奇怪,说明东西已经拿到只差渲染了,原生js不是能成功吗?
<iframe id="myIframe" src="../chart/echart.html"></iframe>
<script src="./response.js"></script>
<script>
const iframe = document.getElementById('myIframe');
iframe.onload = function () {
iframe.contentWindow.postMessage(data, '*');
};
</script>
<div id="main" style="width: 600px;height:400px;"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<script>
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
let option;
window.addEventListener('message', function (event) {
const data = event.data;
document.getElementById('title').innerHTML = '123';
const xx = data.data.dates.slice(0,1000)
const yy = data.data.directionx.slice(0,1000)
option = {
xAxis: { type: 'category', data: xx },
yAxis: { type: 'value' },
series: [{ data: yy, type: 'line', sampling: 'lttb' }]
};
option && myChart.setOption(option);
});
</script>
可以30s为一个刻度,让后台统计每个30秒的均值,图表中默认以30s甚至几分钟一个刻度展示,如果用户放大x轴想看某几分钟内的详情,在让后台返回某个时间段内的所有数据。总之就是提前计算好和只拿需要的数据。
第二个点就是数据传输格式了,可以不用json格式。从你的逻辑可以看出,需要的只是时间点(datas)和时间点对应的浮点值(directionx),那么是否可以用long保存时间戳,double保存浮点值。这样一对数据是16字节,200万对数据的大小是2000000*16/1024/1024 = 30M。你如果还嫌大,并且容忍精度误差,可以用float和int,这样就是15M。
如果是这样传递,你可能需要借助ArrayBuffer和DateView对象提取出来long和double。如果取出来的数不对就考虑一下字节序。
如果你directionx中数据一定是时间连续的,每一分钟都有一条记录的话,那么你的数据包中只需要有一个起始时间和时间间隔就可以了。如果你的directionx数据不连续,但只有极少数时间点缺失。可以通过,时间间隔,多组的【起始时间,结束时间】来表示。
如果你想要做持续推送更新,可以用EventSource,但是注意EventSource传递的是字符串,所以刚刚说的数据格式在发送前可以做一次base64编码,你页面端再做一次base64解码。但数据传输量会是原来的1.33倍。