Apexcharts实现双/多Line图 - 每条线的点数不同 - 第四节

本文介绍了如何在Vue3项目中使用hook和Apexcharts库解决线图中点数不等的问题,通过先绘制散点图再操作SVG元素连线,展示了如何实现在图表中展示每条线的点数不同的双/多线图功能。
摘要由CSDN通过智能技术生成

目录

Vue3 + hook + Apexcharts实现可视化图表渲染的封装 - 第一节 - 基础封装
Vue3 + hook + Apexcharts实现可视化图表渲染的封装 - 第二节 - 图表的全屏功能
Apexcharts实现BoxPlot中绘制散点 - 第三节
Apexcharts实现双/多Line图 - 每条线的点数不同 - 第四节(当前所在)

摘要

Apexcharts中的Line图必须设置 x轴中 catgories,如果不设置默认应该是 index + 1 作为x轴的坐标。但是 categories 是固定的,这时候如果有两条曲线点数不同,绘制上去之后就会出现问题。

实现效果

在这里插入图片描述

思路

Apexcharts中的Line 图并不支持画这种多曲线图,因为 catgories 是固定的x轴也就是固定的了。这种图一般是用来对比线与线之间的趋势,但是每条曲线的坐标个数不同。
换句话来说我们就是要先画坐标点,坐标点个数不同也能画那就是Apexcharts中的 scatter 图,也就是说先画散点图在通过操作 svg 元素将这些点进行连线,同样是和上一节一样进行在 updated 事件中进行 DOM 操作的方式。

代码实现

// 用坐标点画线
const paintLine = (el, points, i) => {
	const colors = ['#8b509d', '#106aa7']
	const svg = el.querySelector('.apexcharts-inner')
	const polyline = document.createElementNS('http://www.w3.org/2000/svg', 'polyline')
	const pointsStr = points.map(point => `${point.x},${point.y}`).join(' ')
	polyline.setAttribute('points', pointsStr)
	polyline.setAttribute('fill', 'none')
	polyline.setAttribute('stroke', colors[i])
	polyline.setAttribute('stroke-width', '2')
	svg.appendChild(polyline)
}

// 画点数不同的line图表;先画散点图,再通过操作DOM的形式连线
export const paintLineChart = (el) => {
	Array.from(el.querySelectorAll('.apexcharts-series')).forEach((item, i) => {
		const pointsArr = Array.from(item.querySelectorAll('circle'))
		// 获取每个点的坐标
		const points = pointsArr.map(point => {
			const x = point.getAttribute('cx')
			const y = point.getAttribute('cy')
			return { x, y }
		})
		paintLine(el, points, i)
	})
}

附上一个完整案例的html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ApexCharts - Mixed Chart with Heatmap and Bar</title>
  <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
</head>
<body>
  <!-- <svg xmlns="http://www.w3.org/2000/svg">
    <polyline points="50,50 100,200 150,150 200,250 250,100" fill="none" stroke="black" />
  </svg> -->
  <div id="chart" style="width: 50vw;"></div>
  <script>
    const colors = ['#8b509d', '#106aa7']
    var options = {
      series: [{
        name: "SAMPLE A",
        // 随机生成20个坐标点
        data: [
        [1.3, 14], [2.7, 18], [4.3, 20], [5.7, 26], [7.3, 38], [8.7, 44], [10.3, 56], [11.7, 64], [13.3, 66], [14.7, 68], [16.3, 70], [17.7, 72], [19.3, 74], [20.7, 76], [22.3, 78], [23.7, 80], [25.3, 82], [26.7, 84], [28.3, 86], [29.7, 88]]
      },{
        name: "SAMPLE B",
        // 随机生成10个坐标点, x轴不能和上面一样
        data: [
        [1, 14], [2, 18], [4, 20], [6, 26], [8, 38], [10, 44], [12, 56], [14, 64], [16, 66], [18, 68], [29.7, 90]]
      }],
      chart: {
        height: 500,
        type: 'scatter',
        zoom: {
          enabled: false,
        }
      },
      xaxis: {
        tickAmount: 10,
        labels: {
          formatter: function(val) {
            return parseFloat(val).toFixed(1)
          }
        }
      },
      yaxis: {
        tickAmount: 7
      },
      markers: {
				size: 1,
			},
      colors: colors,
    };

    var chart = new ApexCharts(document.querySelector("#chart"), options);
    chart.render();

    Array.from(document.querySelectorAll('.apexcharts-series')).forEach((el, i) => {
      const pointsArr = Array.from(el.querySelectorAll('circle'))
      // 获取每个点的坐标
      const points = pointsArr.map(point => {
        const x = point.getAttribute('cx')
        const y = point.getAttribute('cy')
        return { x, y }
      })
      console.log(points)
      paintLine(points, i)
    })

    // 用坐标点画线
    function paintLine(points, i) {
      const svg = document.querySelector('.apexcharts-inner')
      const polyline = document.createElementNS('http://www.w3.org/2000/svg', 'polyline')
      const pointsStr = points.map(point => `${point.x},${point.y}`).join(' ')
      polyline.setAttribute('points', pointsStr)
      polyline.setAttribute('fill', 'none')
      polyline.setAttribute('stroke', colors[i])
      polyline.setAttribute('stroke-width', '2')
      svg.appendChild(polyline)
    }
  </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值