使用烛线图展示二进制01离散量趋势图
自动控制领域里的遥信量一般是离散的只有0 1 两个值的,如果要做图展示需要跟常见的趋势图不同。这里是个例子
<!--此示例下载自 https://echarts.apache.org/examples/zh/editor.html?c=candlestick-touch烛线图,类似粗线是蜡烛身体,细线是火焰。但这个是横着放的。细线代表0,粗线代表1
-->
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head><meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0"><div id="container" style="height: 100%"></div> <script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script><script type="text/javascript">var dom = document.getElementById('container');var myChart = echarts.init(dom, null, {renderer: 'canvas',useDirtyRect: false});var option;// 生成简单的时间轴(每分钟一个数据点)const dates = [];const now = new Date();for (let i = 0; i < 50; i++) {const time = new Date(now.getTime() - (49 - i) * 60000);dates.push(time.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }));}console.log('时间轴:', dates);// 二进制数据 (0, 1) - 0表示细线,1表示粗线// prettier-ignoreconst data = [0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0];console.log('数据:', data);// 为了实现不同线宽但连续的线条,创建分段数据function createSegmentData() {const segments = [];let start = 0;for (let i = 1; i <= data.length; i++) {// 当值发生变化时,或到达数组末尾时,创建一个段if (i === data.length || data[i] !== data[i - 1]) {const segmentData = [];// 创建该段的所有数据点for (let j = start; j < i; j++) {segmentData.push([j, 0.5]);}// 如果不是最后一段,添加下一个点以保证连续性if (i < data.length) {segmentData.push([i, 0.5]);}console.log('分段数据:', segmentData);segments.push({data: segmentData,lineWidth: data[start] === 0 ? 3 : 10,color: data[start] === 0 ? '#52c41a' : '#ff4d4f'});start = i;}}return segments;}const segments = createSegmentData();console.log('分段数据:', segments);option = {animation: false,title: {left: 'center',text: '二进制状态图'},tooltip: {trigger: 'axis',formatter: function (params) {// 用第一个系列的点的全局索引获取时间 // console.log('params------:', params);const globalIndex = params[0].data[0];// params[0].data[params[0].dataIndex][0];const time = dates[globalIndex];let html = time + '<br/>';let p = params[0]; const val = data[globalIndex]; html += `${p.marker}系列A: ` + (val === 0 ? '低电平(0)' : '高电平(1)') + '<br/>'; return html;}},xAxis: {type: 'category',data: dates,boundaryGap: false,axisLine: { lineStyle: { color: '#777' } },axisLabel: {show: true,color: '#666'}},yAxis: {type: 'value',show: false, // 隐藏y轴信息min: 0,max: 1},grid: {left: 20,right: 20,top: 80,bottom: 50},series: segments.map((segment, index) => ({name: `状态段${index}`,type: 'line',data: segment.data,showSymbol: false,lineStyle: {width: segment.lineWidth,color: segment.color}}))};if (option && typeof option === 'object') {myChart.setOption(option);}window.addEventListener('resize', myChart.resize);</script>
</body>
</html>
双系列,多系列
<!--此示例下载自 https://echarts.apache.org/examples/zh/editor.html?c=candlestick-touch烛线图,类似粗线是蜡烛身体,细线是火焰。但这个是横着放的。细线代表0,粗线代表1
-->
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head><meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0"><div id="container" style="height: 100%"></div> <script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script><script type="text/javascript">var dom = document.getElementById('container');var myChart = echarts.init(dom, null, {renderer: 'canvas',useDirtyRect: false});var option;// 生成简单的时间轴(每分钟一个数据点)const dates = [];const now = new Date();for (let i = 0; i < 50; i++) {const time = new Date(now.getTime() - (49 - i) * 60000);dates.push(time.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }));}// 二进制数据 (0, 1) - 0表示细线,1表示粗线// prettier-ignoreconst data = [0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0];console.log('数据:', data);// 第二条离散量数据const data2 = [1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0];console.log('数据2:', data2);// 为了实现不同线宽但连续的线条,创建分段数据function createSegmentData() {const segments = [];let start = 0;for (let i = 1; i <= data.length; i++) {// 当值发生变化时,或到达数组末尾时,创建一个段if (i === data.length || data[i] !== data[i - 1]) {const segmentData = [];// 创建该段的所有数据点for (let j = start; j < i; j++) {segmentData.push([j, 0.5]);}// 如果不是最后一段,添加下一个点以保证连续性if (i < data.length) {segmentData.push([i, 0.5]);}segments.push({data: segmentData,lineWidth: data[start] === 0 ? 3 : 10,color: data[start] === 0 ? '#52c41a' : '#ff4d4f'});start = i;}}return segments;}const segments = createSegmentData();// 第二条线的分段数据生成function createSegmentData2() {const segments = [];let start = 0;for (let i = 1; i <= data2.length; i++) {if (i === data2.length || data2[i] !== data2[i - 1]) {const segmentData = [];for (let j = start; j < i; j++) {segmentData.push([j, 0.2]); // 第二条线y值不同,避免重叠}if (i < data2.length) {segmentData.push([i, 0.2]);}segments.push({data: segmentData,lineWidth: data2[start] === 0 ? 3 : 10,color: data2[start] === 0 ? '#1890ff' : '#faad14' // 蓝色/橙色});start = i;}}return segments;}const segments2 = createSegmentData2();option = {animation: false,title: {left: 'center',text: '二进制状态图'},tooltip: {trigger: 'axis',formatter: function (params) {if (!params || !params.length) return '';// console.log('params------:', params);// const dataIndex = params[0].dataIndex;// const time = dates[dataIndex];const dataIndex = params[0].data[0];// params[0].data[params[0].dataIndex][0];const time = dates[dataIndex];let result = time + '<br/>';let serAry = []for (var i =0;i<params.length;i++) {let item = params[i]; // 判断是第一个系列还是第二个系列let seriesLabel = item.seriesName.startsWith('系列1') ? '系列1' : '系列2';if (serAry.includes(seriesLabel)) {// 已经处理过了,就忽略continue;}serAry.push(seriesLabel);// 判断当前系列用哪个数据源let value = seriesLabel === '系列1' ? data[dataIndex] : data2[dataIndex];let valueText = value === 0 ? '低电平(0)' : '高电平(1)';result += `${seriesLabel}: ${valueText}<br/>`;};return result;}},xAxis: {type: 'category',data: dates,boundaryGap: false,axisLine: { lineStyle: { color: '#777' } },axisLabel: {show: true,color: '#666'}},yAxis: {type: 'value',show: false, // 隐藏y轴信息min: 0,max: 1},grid: {left: 20,right: 20,top: 80,bottom: 50},series: [...segments.map((segment, index) => ({name: `系列1-段${index}`,type: 'line',data: segment.data,showSymbol: false,lineStyle: {width: segment.lineWidth,color: segment.color}})),...segments2.map((segment, index) => ({name: `系列2-段${index}`,type: 'line',data: segment.data,showSymbol: false,lineStyle: {width: segment.lineWidth,color: segment.color}}))]};if (option && typeof option === 'object') {myChart.setOption(option);}window.addEventListener('resize', myChart.resize);</script>
</body>
</html>