ChartJS自定义左侧和底部坐标轴为虚线、顶部为实线边框的实现问题
ChartJS自定义多边框样式实现
需求说明
我有一个ChartJS图表,需要将左侧和底部坐标轴边框设置为虚线,顶部边框设置为单实线,预期效果如下:
初始实现与问题
我最初通过自定义chartAreaBorder插件实现,代码如下:
const chartAreaBorder = { id: 'chartAreaBorder', beforeDraw(chart, args, options) { const { ctx, chartArea: { left, top, width, height } } = chart ctx.save() ctx.strokeStyle = options.borderColor ctx.lineWidth = options.borderWidth ctx.borderStyle = options.borderDash ctx.borderTopWidth = options.borderTopWidth ctx.setLineDash(options.borderDash || []) ctx.lineDashOffset = options.borderDashOffset ctx.strokeRect(left, top, width, height) ctx.restore() } } const config = { type: 'line', data: data, plugins: [ chartAreaBorder ], options: { plugins: { chartAreaBorder: { borderColor: '#b1b1b1', borderWidth: 10, /*borderWidth: { top:0, right:0, left:10, bottom:10 },*/ borderDash: [ 1, 5 ], borderDashOffset: 2, }, } } }
当前得到的效果如下:
遇到的问题是边框被应用到了图表的四个边,找不到隐藏顶部/右侧边框、或是为不同边框单独设置宽度的配置方法,无法实现四个边框分别设置不同样式的需求。
优化后解决方案
感谢@LeeLenalee的帮助,调整后的ChartAreaBorder插件支持为四个边框单独配置宽度、颜色、虚线样式等属性,实现代码如下:
const chartAreaBorder = { id: 'chartAreaBorder', afterDraw: (chart, args, opts) => { const { chartArea: { top, left, width, height }, ctx } = chart const { borders: { tLtR, // 顶部边框(左上到右上) tLbL, // 左侧边框(左上到左下) tRbR, // 右侧边框(右上到右下) bLbR // 底部边框(左下到右下) } } = opts ctx.save() if ( tLtR && tLtR.borderWidth !== 0 ) { ctx.beginPath() ctx.strokeStyle = tLtR.borderColor || Chart.defaults.color ctx.lineWidth = tLtR.borderWidth || 0 ctx.borderStyle = tLtR.borderDash || [] ctx.setLineDash(tLtR.borderDash || []) ctx.lineDashOffset = tLtR.borderDashOffset || 0 ctx.moveTo(left, top + 0.5) ctx.lineTo(left + width, top) ctx.stroke() } if ( tLbL && tLbL.borderWidth !== 0 ) { ctx.beginPath() ctx.strokeStyle = tLbL.borderColor || Chart.defaults.color ctx.lineWidth = tLbL.borderWidth || 0 ctx.borderStyle = tLbL.borderDash || [] ctx.setLineDash(tLbL.borderDash || []) ctx.lineDashOffset = tLbL.borderDashOffset || 0 ctx.moveTo(left, top) ctx.lineTo(left, top + height - 5) ctx.stroke() } if ( tRbR && tRbR.borderWidth !== 0 ) { ctx.beginPath() ctx.strokeStyle = tRbR.borderColor || Chart.defaults.color ctx.lineWidth = tRbR.borderWidth || 0 ctx.borderStyle = tRbR.borderDash || [] ctx.setLineDash(tLbL.borderDash || []) ctx.lineDashOffset = tRbR.borderDashOffset || 0 ctx.moveTo(left + width, top) ctx.lineTo(left + width, top + height) ctx.stroke() } if ( bLbR && bLbR.borderWidth !== 0 ) { ctx.beginPath() ctx.strokeStyle = bLbR.borderColor || Chart.defaults.color ctx.lineWidth = bLbR.borderWidth || 0 ctx.borderStyle = bLbR.borderDash || [] ctx.setLineDash(bLbR.borderDash || []) ctx.lineDashOffset = bLbR.borderDashOffset || 0 ctx.moveTo(left, top + height) ctx.lineTo(left + width, top + height) ctx.stroke() } ctx.restore() } } // 插件配置示例 plugins: { chartAreaBorder: { borders: { tLtR: { // 顶部边框:实线 borderWidth: 1, borderColor: '#b1b1b1' }, tLbL: { // 左侧边框:虚线 borderDash: [ 1, 5 ], borderWidth: 10, borderColor: '#b1b1b1' }, tRbR: { // 右侧边框:隐藏 borderWidth: 0 }, bLbR: { // 底部边框:虚线 borderDash: [ 1, 5 ], borderWidth: 10, borderColor: '#b1b1b1' }, } } }
内容的提问来源于stack exchange,提问作者soDub
相关产品推荐
相关产品推荐

