关于echarts一种另类散点图的做法

目前需求是要做散点图,但要求不能重叠,得横着排,这就很为难,因为我的轴是时间轴,考虑之后打算采取柱状图的方式去实现,隐藏掉柱子,只显示散点图的图标。这就可以完美解决这个问题
需求图:
需求图
初步实现效果:
在这里插入图片描述
我和后端那边商量在最大放大档是一小时内数据只显示在这个小时的刻度线上,但只要滚轮放大,就显示到真实的点上。当然还是会有重叠的情况,但没必要去考虑的太细,一方面本省就不符合坐标轴的逻辑,第二那我还要考虑视口宽度,太麻烦了,最后还可能吃力不讨好,觉得做到这种程度其实也差不多,至于到秒级事件触发过于频繁,就需要后端那边去处理了,去掉那些重复事件
代码的话有一个地方要注意就是要处理空数据占位的问题,比如我8种点,可能有1、3、7有数据,如果占位就会特别别扭,这就需要居中,网上也有多列柱状图无数据剧中的方案,我的具体代码是这样的:
因为我的代码涉及到具体的业务,就没有粘贴全部,只是关键代码,就是在显示tooltip时,为了能正常显示,所以我还是做了一级不优化居中效果的柱状图,去专门显示

   // 有几个要显示的时间点
    const xAxis = [
        new Date('2024-06-16 13:00:01').getTime(),
        new Date('2024-06-16 15:00:00').getTime(),
        new Date('2024-06-16 17:00:00').getTime(),
        new Date('2024-06-16 19:00:00').getTime(),
    ];
    // 有几种要显示的事件
    const bar = [
        [10, 2, 0],
        [8, 2, 0],
        [0, 0, 2],
        [0, 0, 2],
        [0, 0, 2],
        [0, 0, 2],
        [0, 0, 2],
        [0, 0, 2],
    ];

	function dealBar(arr: Array<number>, name: string) {
        const bar: any = [];
        arr.forEach((item: number, index: number) => {
            const data = [];
            for (let i = 0; i < index; i++) {
                data.push('');
            }
            if (item) {
                data.push([xAxis[index], item]);
                bar.push({
                    name,
                    type: 'pictorialBar',
                    symbolSize: 16,
                    symbol: 'circle',
                    xAxisIndex: index + 1,
                    barWidth: 16,
                    barGap: 0,
                    symbolPosition: 'end',
                    data,
                });
            }
        });
        return bar;
    }


	// echarts
 tooltip: {
           trigger: 'axis',
           alwaysShowContent: false,
           axisPointer: {
               snap: false,
           },
       },
  xAxis: [
         {
             type: 'time',
             position: 'bottom',
             min: timeStart,
             max: timeEnd,
             axisLabel: {
                 // 格式化x轴显示
                 formatter: function (value: any) {
                     if (level >= 4 && level < 6) {
                         // 其他的时间返回格式化 00:00
                         return moment(value).format('HH:mm:ss');
                     } else if (level >= 6) {
                         return moment(value).format('HH:mm:ss');
                     } else {
                         return moment(value).format('HH:mm');
                     }
                 },
             },
             scale: true,
             minInterval: 1,
             splitNumber: 10,
             splitLine: { show: false },
             axisPointer: {
                 type: 'line',
             },
             axisTick: { show: false },
         },
         ...xAxis.map(item => {
             let data = item;
             return {
                 type: 'time',
                 position: 'bottom',
                 data,
                 min: timeStart,
                 max: timeEnd,
                 axisLabel: {
                     show: false,
                     // 格式化x轴显示
                     formatter: function (value: any) {
                         return moment(value).format('HH:mm');
                     },
                 },
                 splitNumber: 10,
                 splitLine: { show: false },
                 axisPointer: {
                     show: false,
                 },
                 axisTick: { show: false },
             };
         }),
     ],
	// echarts series代码
	 series: [
            ...dealBar(bar[0], '气流受限事件'),
            ...dealBar(bar[1], '参数改变事件'),
            ...dealBar(bar[2], '阻塞性事件'),
            ...dealBar(bar[3], '中枢性事件'),
            ...dealBar(bar[4], '鼾声事件'),
            ...dealBar(bar[5], '氧减事件'),
            ...dealBar(bar[6], '低通气事件'),
            ...dealBar(bar[7], '报警事件'),

            // tooltip,为了保证tooltip的正常显示
            {
                name: '气流受限事件',
                type: 'pictorialBar',
                symbolSize: 16,
                symbol: 'none',
                data: bar[0].map((item, index) => {
                    if (item) {
                        return [xAxis[index], item];
                    } else {
                        return '';
                    }
                }),
                barWidth: 16,
                barGap: 0,
                symbolPosition: 'end',
                xAxisIndex: 0,
            },
            {
                name: '参数改变事件',
                type: 'pictorialBar',
                symbolSize: 16,
                symbol: 'none',
                data: bar[1].map((item, index) => {
                    if (item) {
                        return [xAxis[index], item];
                    } else {
                        return '';
                    }
                }),
                barGap: 0,
                barWidth: 16,
                symbolPosition: 'end',
                xAxisIndex: 0,
            },
            {
                name: '阻塞性事件',
                type: 'pictorialBar',
                symbolSize: 16,
                symbol: 'none',
                data: bar[2].map((item, index) => {
                    if (item) {
                        return [xAxis[index], item];
                    } else {
                        return '';
                    }
                }),
                barGap: 0,
                barWidth: 16,
                symbolPosition: 'end',
                xAxisIndex: 0,
            },
            {
                name: '中枢性事件',
                type: 'pictorialBar',
                symbolSize: 16,
                symbol: 'none',
                data: bar[3].map((item, index) => {
                    if (item) {
                        return [xAxis[index], item];
                    } else {
                        return '';
                    }
                }),
                barGap: 0,
                barWidth: 16,
                symbolPosition: 'end',
                xAxisIndex: 0,
            },
            {
                name: '鼾声事件',
                type: 'pictorialBar',
                symbolSize: 16,
                symbol: 'none',
                data: bar[4].map((item, index) => {
                    if (item) {
                        return [xAxis[index], item];
                    } else {
                        return '';
                    }
                }),
                barGap: 0,
                barWidth: 16,
                symbolPosition: 'end',
                xAxisIndex: 0,
            },
            {
                name: '氧减事件',
                type: 'pictorialBar',
                symbolSize: 16,
                symbol: 'none',
                data: bar[5].map((item, index) => {
                    if (item) {
                        return [xAxis[index], item];
                    } else {
                        return '';
                    }
                }),
                barGap: 0,
                barWidth: 16,
                symbolPosition: 'end',
                xAxisIndex: 0,
            },
            {
                name: '低通气事件',
                type: 'pictorialBar',
                symbolSize: 16,
                symbol: 'none',
                data: bar[6].map((item, index) => {
                    if (item) {
                        return [xAxis[index], item];
                    } else {
                        return '';
                    }
                }),
                barGap: 0,
                barWidth: 16,
                symbolPosition: 'end',
                xAxisIndex: 0,
            },
            {
                name: '报警事件',
                type: 'pictorialBar',
                symbolSize: 16,
                symbol: 'none',
                data: bar[7].map((item, index) => {
                    if (item) {
                        return [xAxis[index], item];
                    } else {
                        return '';
                    }
                }),
                barGap: 0,
                barWidth: 16,
                symbolPosition: 'end',
                xAxisIndex: 0,
            },
        ],

要在echarts地图上显示散点图,需要在series(系列列表配置)中添加两个图表配置,通过修改type值,决定图表类型(散点图和地图)。具体步骤如下: 1.在html文件中引入echarts.js文件。 2.在html文件中创建一个div元素,用于显示echarts地图。 3.在JavaScript文件中定义一个echarts实例,并将其与div元素关联。 4.在JavaScript文件中定义一个option对象,用于配置echarts地图。 5.在option对象中添加series(系列列表配置)配置项,用于添加散点图和地图。 6.在series配置项中添加两个图表配置,一个用于散点图,一个用于地图。 7.在散点图配置中,设置type为scatter,然后设置data为散点图的数据。 8.在地图配置中,设置type为map,然后设置mapType为地图类型,设置data为地图的数据。 9.最后,调用echarts实例的setOption方法,将option对象传递给它,以显示echarts地图。 下面是一个示例代码,用于在echarts地图上显示散点图: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>ECharts</title> <script src="https://cdn.jsdelivr.net/npm/echarts@5.2.1/dist/echarts.min.js"></script> </head> <body> <div id="main" style="width: 600px;height:400px;"></div> <script> var myChart = echarts.init(document.getElementById('main')); var option = { series: [ { type: 'scatter', data: [[10, 20], [20, 30], [30, 40], [40, 50]] }, { type: 'map', mapType: 'china', data: [ {name: '北京', value: Math.round(Math.random() * 1000)}, {name: '天津', value: Math.round(Math.random() * 1000)}, {name: '上海', value: Math.round(Math.random() * 1000)}, {name: '重庆', value: Math.round(Math.random() * 1000)}, {name: '河北', value: Math.round(Math.random() * 1000)}, {name: '河南', value: Math.round(Math.random() * 1000)}, {name: '云南', value: Math.round(Math.random() * 1000)}, {name: '辽宁', value: Math.round(Math.random() * 1000)}, {name: '黑龙江', value: Math.round(Math.random() * 1000)}, {name: '湖南', value: Math.round(Math.random() * 1000)}, {name: '安徽', value: Math.round(Math.random() * 1000)}, {name: '山东', value: Math.round(Math.random() * 1000)}, {name: '新疆', value: Math.round(Math.random() * 1000)}, {name: '江苏', value: Math.round(Math.random() * 1000)}, {name: '浙江', value: Math.round(Math.random() * 1000)}, {name: '江西', value: Math.round(Math.random() * 1000)}, {name: '湖北', value: Math.round(Math.random() * 1000)}, {name: '广西', value: Math.round(Math.random() * 1000)}, {name: '甘肃', value: Math.round(Math.random() * 1000)}, {name: '山西', value: Math.round(Math.random() * 1000)}, {name: '内蒙古', value: Math.round(Math.random() * 1000)}, {name: '陕西', value: Math.round(Math.random() * 1000)}, {name: '吉林', value: Math.round(Math.random() * 1000)}, {name: '福建', value: Math.round(Math.random() * 1000)}, {name: '贵州', value: Math.round(Math.random() * 1000)}, {name: '广东', value: Math.round(Math.random() * 1000)}, {name: '青海', value: Math.round(Math.random() * 1000)}, {name: '西藏', value: Math.round(Math.random() * 1000)}, {name: '四川', value: Math.round(Math.random() * 1000)}, {name: '宁夏', value: Math.round(Math.random() * 1000)}, {name: '海南', value: Math.round(Math.random() * 1000)}, {name: '台湾', value: Math.round(Math.random() * 1000)}, {name: '香港', value: Math.round(Math.random() * 1000)}, {name: '澳门', value: Math.round(Math.random() * 1000)} ] } ] }; myChart.setOption(option); </script> </body> </html> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值