Highcharts scrollablePlotArea不渲染plotlines,仅显示标记点问题
问题:Highcharts移动端模态框中plotlines首次加载仅显示可视区域部分
- 已实现绘图区域数据展示逻辑,设置图表宽度小于700px时启用
scrollablePlotArea - 移动端/平板设备上,模态框首次加载图表时,plotlines仅显示可视区域内的部分,但标记点可沿对应线条正常显示
- 切换图例后图表可完整渲染,桌面端无此问题
- 尝试设置
scrollPositionX: 1不符合需求(希望滚动区域从图表起始位置开始) - 询问是否需要在滚动时重渲染图表,并寻求解决方案
相关代码
图表配置代码
return { chartOptions: { credits: { enabled: false }, chart: { spacingLeft: 0, spacingTop: 0, backgroundColor: "transparent", className: 'highcharts', style: { fontFamily: '"Open Sans",sans-serif' }, type: 'spline', plotBackgroundColor: null, plotBorderWidth: 0, plotShadow: false, height: this.height, marginLeft: 40, marginBottom: 120, marginTop: 40 }, responsive: { rules: [{ condition: { maxWidth: 700 }, chartOptions: { chart: { height: 450, scrollablePlotArea: { minWidth: 700, scrollPositionX: 0 } } } }, { condition: { minWidth: 700 }, chartOptions: { chart: { height: 650 } } }] }, exporting: { enabled: false // hide button }, title: { text: '' }, subtitle: { text: '' }, xAxis: { tickInterval: 200, // reversed: true labels: { enabled: false }, plotLines: (resultsDataNew.intendedOccupancy == 'Homestead') ?[{ color: '#808080', // Color value dashStyle: 'solid', // Style of the plot line. Default to solid value: 1300, // Value of where the line will appear width: 1, // Width of the line, label: { text: 'AIO HELOC draw access terminates', verticalAlign: 'middle', textAlign: 'center', style: { color: 'red', fontSize: 9, fontWeight: 'bold' } } }] : [{ color: '#808080', // Color value dashStyle: 'solid', // Style of the plot line. Default to solid value: 1300, // Value of where the line will appear width: 0 // Width of the line }] }, yAxis: { title: { text: '' }, tickAmount: 6, plotLines: [{ value: 0, width: 1, color: '#808080' }] }, tooltip: { formatter: function () { return '<b>Week - </b>'+ this.points.reduce(function (s, point) { return s + '<br/>' + point.series.name + ': ' + currency(point.y).format() ; }, '<b>' + this.x + '</b>'); }, shared: true, }, series: [{ name: 'All In One Loan Credit Limit', data: this.DataZ[0].value, marker: { symbol: 'square', } }, { name: 'All In One Loan Principal Balance', data: this.DataX[0].value, marker: { symbol: 'square', } }, { name: 'Traditional Mortgage Principal Balance', data: this.DataY[0].value, showInLegend: this.DataY[0].value !== undefined, marker: { symbol: 'square', } }], legend: { layout: 'vertical', align: 'center', verticalAlign: 'bottom', floating: false, }, } }; }
Vue模板代码
<template> <div class="chart-container" style="position: relative; width:auto; height:auto" > <div class="chart-wrapper"> <div class="chart"> <highcharts ref="highcharts" :options="chartOptions"></highcharts> </div> </div> </div> </template> <script> import {Chart} from "highcharts-vue"; import currency from "currency.js"; import Highcharts from "highcharts"; import exportingInit from "highcharts/modules/exporting"; import stockInit from "highcharts/modules/stock"; import offlineExporting from "highcharts/modules/offline-exporting"; import accessibility from "highcharts/modules/accessibility"; stockInit(Highcharts); exportingInit(Highcharts); offlineExporting(Highcharts); accessibility(Highcharts); export default { name: "ExpandedPaydown", components: { highcharts: Chart, }, props: { Weeks: { type: Array, default: () => [], }, DataX: { type: Array, default: () => [], }, DataY: { type: Array, default: () => [], }, DataZ: { type: Array, default: () => [], }, height: { type: Number, default: 350 }, expandGraph: { type: Boolean, default: false, } }, </script>
SCSS样式代码
<style lang="scss" scoped> @import "../../../styles/core/mixins.scss"; .chart-container { display: flex; flex-direction: column; align-items: flex-start; } .chart-wrapper { background-color: transparent; display: flex; flex-direction: row; align-items: flex-start; width: 100%; z-index: 0; @include media(xxl) { flex-direction: column; align-items: center; } @include media(md) { flex-direction: row; } @include media(sm) { flex-direction: column; align-items: center; } } .chart { margin: 0; font-size: 1rem; text-align: center; z-index: 0; border: 1px solid grey; padding: 20px; width: 100%; height: auto; @include media(md) { max-width:100%; } @include media(sm) { border: 0px; max-width: 100%; } } </style>
解决方案
1. 模态框显示后触发图表重绘
模态框首次渲染时,容器尺寸可能未完全计算,导致Highcharts绘制plotlines时仅考虑可视区域。监听模态框显示状态(如expandGraph属性),延迟执行重绘:
watch: { expandGraph(newVal) { if (newVal) { setTimeout(() => { const chart = this.$refs.highcharts.chart; if (chart) { chart.reflow(); // 可选:手动更新plotlines确保完整渲染 chart.xAxis[0].update({ plotLines: chart.xAxis[0].options.plotLines }); } }, 300); } } }
2. 动态初始化scrollablePlotArea
移除响应式规则中的scrollablePlotArea设置,改为在图表挂载后根据容器尺寸动态添加,避免初始化时的尺寸计算偏差:
mounted() { this.$nextTick(() => { const chart = this.$refs.highcharts.chart; if (chart && chart.chartWidth < 700) { chart.update({ chart: { scrollablePlotArea: { minWidth: 700, scrollPositionX: 0 } } }, true); // true表示立即重绘 } }); }
3. 手动扩展plotlines绘制范围
在图表加载完成事件中,调整plotlines的SVG路径,确保覆盖整个滚动区域:
chart: { // ...其他配置 events: { load() { const chart = this; if (chart.chartWidth < 700) { chart.xAxis[0].plotLines.forEach(plotLine => { const path = plotLine.svgElem.d.split(' '); // 将路径终点扩展到滚动区域最大宽度 path[2] = chart.chartWidth + chart.scrollablePlotArea.scrollbarWidth; plotLine.svgElem.attr('d', path.join(' ')); }); } } } }
内容的提问来源于stack exchange,提问作者Claude M
相关产品推荐
相关产品推荐

