Angular中Highcharts折线图与Plot Line交点区域填充实现求助
嗨,我来帮你搞定这个Highcharts的区域填充需求!要实现第一条折线和y轴水平plotLine的交集区域高亮,我们可以通过计算交点并动态添加区域系列来完成,具体步骤和修改后的代码如下:
实现思路
- 计算折线与plotLine的交点:由于折线的点是离散的,我们需要遍历相邻点对,判断是否跨越了plotLine的y值(76500),再用线性插值算出交点的精确坐标。
- 构建填充区域的数据集:收集折线中位于plotLine上方的点、交点,再加上plotLine的x轴端点,形成一个闭合的区域数据集合。
- 添加区域系列:动态创建一个
area类型的系列,用半透明红色填充区域,同时隐藏不必要的交互和图例,避免干扰原图表。
修改后的完整代码
Highcharts.chart('container', { title: { text: 'Solar Employment Growth by Sector, 2010-2016' }, subtitle: { text: 'Source: thesolarfoundation.com' }, yAxis: { title: { text: 'Number of Employees' }, plotLines: [{ color: '#FF0000', width: 2, value: 76500 }] }, xAxis: { accessibility: { rangeDescription: 'Range: 2010 to 2017' } }, legend: { layout: 'vertical', align: 'right', verticalAlign: 'middle' }, plotOptions: { series: { label: { connectorAllowed: false }, pointStart: 2010 }, area: { fillColor: { linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, stops: [ [0, Highcharts.color('#FF0000').setOpacity(0.3).get('rgba')], [1, Highcharts.color('#FF0000').setOpacity(0.1).get('rgba')] ] }, lineWidth: 0, marker: { enabled: false }, enableMouseTracking: false, showInLegend: false } }, series: [ { name: 'Installation', data: [143934, 52503, 57177, 69658, 97031, 119931, 137133, 154175] }, { name: 'Installation2', data: [14393, 2503, 7177, 9658, 7031, 19931, 13133, 14175] } ], chart: { events: { load: function() { const chart = this; const targetSeries = chart.series[0]; // 目标为第一条折线系列 const plotLineY = 76500; // plotLine的固定y值 const areaData = []; const points = targetSeries.points; // 遍历相邻点对,计算交点并收集区域数据 for (let i = 0; i < points.length - 1; i++) { const point1 = points[i]; const point2 = points[i + 1]; // 判断当前点对是否跨越了plotLine const crossesPlotLine = (point1.y < plotLineY && point2.y > plotLineY) || (point1.y > plotLineY && point2.y < plotLineY); if (crossesPlotLine) { // 线性插值计算交点的x坐标 const x = point1.x + (plotLineY - point1.y) * (point2.x - point1.x) / (point2.y - point1.y); const intersectionPoint = [x, plotLineY]; // 将plotLine上方的折线点加入区域数据 if (point1.y > plotLineY) areaData.push([point1.x, point1.y]); // 加入交点 areaData.push(intersectionPoint); // 将下一个在plotLine上方的点加入 if (point2.y > plotLineY) areaData.push([point2.x, point2.y]); } else if (point1.y > plotLineY) { // 点本身就在plotLine上方,直接加入 areaData.push([point1.x, point1.y]); } } // 处理最后一个点 const lastPoint = points[points.length - 1]; if (lastPoint.y > plotLineY) areaData.push([lastPoint.x, lastPoint.y]); // 加入plotLine的两端点,形成闭合区域 areaData.push([points[points.length - 1].x, plotLineY]); areaData.push([points[0].x, plotLineY]); // 动态添加填充区域系列 chart.addSeries({ type: 'area', data: areaData }); } } } });
<script src="https://code.highcharts.com/highcharts.js"></script> <script src="https://code.highcharts.com/modules/series-label.js"></script> <script src="https://code.highcharts.com/modules/exporting.js"></script> <script src="https://code.highcharts.com/modules/export-data.js"></script> <script src="https://code.highcharts.com/modules/accessibility.js"></script> <figure class="highcharts-figure"> <div id="container"></div> <p class="highcharts-description"> Basic line chart showing trends in a dataset. This chart includes the <code>series-label</code> module, which adds a label to each line for enhanced readability. </p> </figure>
小提示
如果你的需求是填充折线在plotLine下方的区域,只需要把代码中所有判断> plotLineY的地方改成< plotLineY就可以啦!
内容的提问来源于stack exchange,提问作者Manoj Rejinthala
相关产品推荐
相关产品推荐

