Apexcharts实现BoxPlot中绘制散点 - 第三节

目录

Vue3 + hook + Apexcharts实现可视化图表渲染的封装 - 第一节 - 基础封装
Vue3 + hook + Apexcharts实现可视化图表渲染的封装 - 第二节 - 图表的全屏功能
Apexcharts实现BoxPlot中绘制散点 - 第三节 (当前所在)

摘要

当我们通过Apexcharts绘制BoxPlot前要知道BoxPlot的五个值代表分别代表:最小值,最大值,中位数,上四分位数,下四分位数,这五个数值是根据一组数据计算出来的。这时候我想在BoxPlot中显示这些数据点的分布时,我们通过查阅Apexcharts文档知道并不能满足此功能,只有类似下图的功能:
在这里插入图片描述
如果你按照文档里的例子实现是所有的点会在每个图例的中轴形成一条直性,并不是我们想要的散点图。我们想要的实现效果应该是下面那样,点是分布在每个图例中的。如下:

实现效果

在这里插入图片描述

思路

当我们从后端获取到数据之后,将数据更新到图表中时,会触发 updated 事件,通过监听这个事件在图表绘制完成时我们通过操作 DOM 的方式,收到绘制这些散点。就是获取画好的 BoxPlotsvg 元素,然后生成散点的 svg 将其 append 进去。

代码实现

注意:data 为后端或者自己格式化后的数组,如果不同代码里的逻辑需要更改

// 绘制散点
const paintCircle = (el, value, cx, cy) => {
	const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')
	circle.setAttribute('cx', cx)
	circle.setAttribute('cy', cy)
	circle.setAttribute('r', 4)

	return circle
}

/**
 * 绘制BoxPlot上的散点图
 * @param {*} el
 * @param {*} data 格式为[[x, [y1, y2, y3], [all data]], [x, [y1, y2, y3], [all data]]
 * @param {*} special 当为true时,表示绘制的是特殊的BoxPlot,data的格式为{series, yaxis, allData}
 */
export const paintBoxPlotScatter = (el, data) => {
	let min = 0, max = 1

	const { min: _min, max: _max } = getBoxPlotMinAndMax(data)
	min = _min
	max = _max

	const interval = max - min
	const target = el.querySelector('svg')
	const allGSvg = document.createElementNS('http://www.w3.org/2000/svg', 'g')
	const height = target.querySelector('.apexcharts-xcrosshairs').getAttribute('height')
	const barWidth = target.querySelector('.apexcharts-series path').getAttribute('barWidth')
	const transform = target.querySelector('.apexcharts-inner').getAttribute('transform')
	allGSvg.setAttribute('class', 'scatter-g')
	allGSvg.setAttribute('transform', transform)

	data.forEach((item, index) => {
		const gSvg = document.createElementNS('http://www.w3.org/2000/svg', 'g')
		gSvg.setAttribute('fill', '#c9a2ca')

		const xValue = target.querySelectorAll('.apexcharts-xaxis-tick')[index].getAttribute('x1')
		// 遍历每个散点值
		item[2].forEach(sItem => {
			// 计算每个散点的坐标, cx以xValue为中心然后生成随机便宜量
			const cx = +xValue + _.random(-barWidth / 2, barWidth / 2)
			// 根据height和interval计算cy
			const cy = height - (sItem - min) / interval * height

			gSvg.appendChild(paintCircle(el, sItem, cx, cy))
		})

		allGSvg.appendChild(gSvg)
	})

	target.appendChild(allGSvg)
}
  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值