highcharts-multicolor-series
Version:
Highcharts plugin that adds new series: multicolor-series, where you can define color for each part of a path, between two points.
25 lines (23 loc) • 6.36 kB
JavaScript
/**
* Multicolor Series v3.1.1 (2025-06-02)
*
* (c) 2012-2025 Black Label
*
* License: MIT
*/
(function(){
(function(t){"object"===typeof module&&module.exports?module.exports=t:t(Highcharts)})(function(t){const {isArray:A,pick:B,SeriesRegistry:v,Series:C}=t,w=b=>{let c=!1;for(let a=0;a<b.length;a++){if("string"===typeof b[a]&&"number"===typeof b[a+1]&&"number"===typeof b[a+2])c=!0;else{c=!1;break}a+=2}return c};class z extends v.seriesTypes.line{constructor(){super();this.getSegment=(b,c)=>{const a=this.options,d=a.dashStyle,e="square"!==a.linecap;c={stroke:c,"stroke-width":a.lineWidth,fill:"none",zIndex:1};
let g;d?c.dashstyle=d:e&&(c["stroke-linecap"]=c["stroke-linejoin"]="round");b[1]&&(c.stroke=b[1]);w(b[0])&&(g=this.chart.renderer.path(b[0]).attr(c).add(this.group));(null===g||void 0===g?0:g.shadow)&&g.shadow(!!a.shadow);return g};this.segments=[];this.singlePoints=[];this.graphPaths=[];this.areaPaths=[];this.graphs=[]}getPath(b){let c=[];b&&b.forEach(a=>{A(a[0])&&(c=c.concat(a[0]))});return c}getSegmentPath(b){const c=[],a=this.options.step;b.forEach((d,e)=>{const g=Number(d.plotX);d=Number(d.plotY);
c.push(e?"L":"M");if(a&&e){e=b[e-1];const f=Number(e.plotX);"right"===a?c.push(e.plotX,d,"L"):"center"===a?c.push((f+g)/2,e.plotY,"L",(f+g)/2,d,"L"):c.push(g,e.plotY,"L")}c.push(g,d)});return c}formatTrackerPath(b){var c,a,d,e;const g=this.options,f=b.length,h=this.singlePoints,k=null!==(a=null===(c=this.chart.options.tooltip)||void 0===c?void 0:c.snap)&&void 0!==a?a:0;if(f&&!g.trackByArea)for(c=f+1;c--;)if("M"===(null===(d=b[c])||void 0===d?void 0:d.toString())&&(a=b[c+1],"number"===typeof a&&b.splice(c+
1,0,a-k,b[c+2],"L")),c&&"M"===(null===(e=b[c])||void 0===e?void 0:e.toString())||c===f)a=b[c-2],"number"===typeof a&&b.splice(c,0,"L",a+k,b[c-1]);for(c=0;c<h.length;c++)d=h[c],e=Number(d.plotX),b.push("M",e-k,d.plotY,"L",e+k,d.plotY);return b}drawTracker(){var b,c,a;const d=this,e=d.options,g=e.trackByArea;var f=this.getPath(d.graphPaths);const h=d.chart,k=h.pointer,l=h.renderer,r=null!==(c=null===(b=h.options.tooltip)||void 0===b?void 0:b.snap)&&void 0!==c?c:0;b=d.tracker;const n=(c=e.cursor)&&{cursor:c},
p=()=>{if(h.hoverSeries!==d)d.onMouseOver()};f=this.formatTrackerPath(f);w(f)&&(b?b.attr({d:f}):(d.tracker=l.path(f).attr({"stroke-linejoin":"round",visibility:d.visible?"visible":"hidden",stroke:"rgba(192,192,192,0.002)",fill:g?"rgba(192,192,192,0.002)":"none","stroke-width":null!==(a=e.lineWidth)&&void 0!==a?a:g?0:2*r,zIndex:2}).add(d.group),[d.tracker,d.markerGroup].forEach(q=>{if(q&&(q.addClass("highcharts-tracker").on("mouseover",p).on("mouseout",u=>{if(k)k.onTrackerMouseOut(u)}),n&&q.css(n),
"undefined"!==typeof document.documentElement.ontouchstart))q.on("touchstart",p)})))}setState(b,c){var a,d,e,g;c=this.options;const f=this.graphs,h=c.states;let k=null!==(a=c.lineWidth)&&void 0!==a?a:0;b=b||"";this.state!==b&&(this.state=b,!h||!b||!1!==(null===(d=h.hover)||void 0===d?void 0:d.enabled)&&!1!==(null===(e=h.inactive)||void 0===e?void 0:e.enabled))&&(h&&b&&(k=(null===(g=h[b])||void 0===g?void 0:g.lineWidth)||k+1),f&&f.forEach(l=>{l.dashstyle||l.attr({"stroke-width":k})}))}getSegments(){var b,
c;const a=this.points;let d=[],e=0,g=a.length;if(g)if(this.options.connectNulls){for(let f=g-1;0<=f;--f)null===a[f].y&&a.splice(f,1);g=a.length;a.forEach((f,h)=>{var k;0<h&&a[h].segmentColor!==a[h-1].segmentColor&&(d.push({points:a.slice(e,h+1),color:null!==(k=a[h-1].segmentColor)&&void 0!==k?k:""}),e=h)});g&&e!==g-1&&d.push({points:a.slice(e,g),color:null!==(b=a[g-1].segmentColor)&&void 0!==b?b:""});0<a.length&&0===d.length&&(d=[{color:null!==(c=a[0].segmentColor)&&void 0!==c?c:"",points:a}])}else{let f=
null;a.forEach((h,k)=>{var l,r,n,p;const q=0<k&&(null===h.y||null===a[k-1].y||h.segmentColor!==a[k-1].segmentColor&&a[k].segmentColor!==f),u=!(null===(l=a[k-1])||void 0===l||!l.segmentColor||null===a[k-1].y);let m=a.slice(e,k+1);q?0<m.length&&(m.forEach((x,y)=>{null===x.y&&m.splice(y,1)}),d.push({points:m,color:null!==(r=u?a[k-1].segmentColor:f)&&void 0!==r?r:""}),e=k):k===g-1&&(l=k+1,null===h.y&&l--,m=a.slice(e,l),0<m.length&&(m.forEach((x,y)=>{null===x.y&&m.splice(y,1)}),d.push({points:m,color:null!==
(n=u?a[k-1].segmentColor:f)&&void 0!==n?n:""}),e=k));h&&(f=null!==(p=h.segmentColor)&&void 0!==p?p:"")})}this.segments=d}setSeriesGraphPathsAndSinglePoints(){const b=this,c=[];let a=[],d;b.segments.forEach(e=>{d=b.getSegmentPath(e.points);1<e.points.length?c.push([d,e.color]):a=[...a,...e.points]});b.singlePoints=a;return b.graphPaths=c}drawGraph(){const b=this,c=b.options.lineColor||b.color||"";var a=b.setSeriesGraphPathsAndSinglePoints();const d=a.length;let e=0,g=b.graphs;g?a.forEach((f,h)=>{b.graphs[h]&&
w(f[0])?b.graphs[h].attr({d:f[0],stroke:f[1]}):(f=this.getSegment(f,c))&&(b.graphs[h]=f)}):0<a.length&&(g=[],a.forEach((f,h)=>{(f=this.getSegment(f,c))&&(g[h]=f)}),b.graphs=g);e=b.graphs&&b.graphs.length||-1;for(a=e;a>=d;a--)b.graphs&&b.graphs[a]&&(b.graphs[a].destroy(),b.graphs.splice(a,1))}translate(){super.translate.apply(this,arguments);this.getSegments&&this.getSegments()}}v.registerSeriesType("coloredline",z);class D extends z{constructor(){super();this.segments=[];this.singlePoints=[]}init(b,
c){C.prototype.init.call(this,b,c)}closeSegment(b,c,a){b.push("L",c[c.length-1].plotX,a,"L",c[0].plotX,a)}drawGraph(){var b;super.drawGraph.call(this);const c=this;c.graphs&&(null===(b=null===c||void 0===c?void 0:c.graphPaths)||void 0===b||b.forEach((a,d)=>{c.graphs[d]&&c.graphs[d].attr({fill:a[1]})}))}getSegmentPath(b){var c,a;const d=[],e=this.options,g=this.options.threshold;null===e.threshold&&(this.options.threshold=null!==(c=this.yAxis.min)&&void 0!==c?c:0);c=this.yAxis.getThreshold(null!==
(a=e.threshold)&&void 0!==a?a:0);a=super.getSegmentPath.call(this,b);d.push(...a);3===a.length&&d.push("L",a[1],a[2]);if(e.stacking)for(let f=b.length-1;0<=f;f--)a=B(b[f].yBottom,c),f<b.length-1&&e.step&&d.push(b[f+1].plotX,a),d.push(b[f].plotX,a);else this.closeSegment(d,b,c);this.options.threshold=g;return d}setSeriesGraphPathsAndSinglePoints(){const b=this,c=[];let a=[],d;this.areaPaths=[];b.segments.forEach(e=>{d=b.getSegmentPath(e.points);1<e.points.length?c.push([d,e.color]):a=[...a,...e.points]});
b.singlePoints=a;return b.graphPaths=c}}v.registerSeriesType("coloredarea",D)});
}).call(this)
//# sourceMappingURL=multicolor-series.min.js.map