highcharts
Version:
JavaScript charting framework
13 lines • 11.9 kB
JavaScript
/**
* Highcharts JS v13.0.1 (2026-08-17)
* @module modules/arc-diagram
* @requires highcharts/modules/sankey
*
* Arc diagram module
*
* (c) 2021-2026 Highsoft AS
* Author: Piotr Madej
*
* A commercial license may be required depending on use,
* see www.highcharts.com/license
*/import*as t from"../highcharts.js";let e={};e.n=t=>{let o=t&&t.__esModule?()=>t.default:()=>t;return e.d(o,{a:o}),o},e.d=(t,o)=>{if(Array.isArray(o))for(var s=0;s<o.length;){var i=o[s++],n=o[s++];e.o(t,i)?0===n&&s++:0===n?Object.defineProperty(t,i,{enumerable:!0,value:o[s++]}):Object.defineProperty(t,i,{enumerable:!0,get:n})}else for(var i in o)e.o(o,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:o[i]})},e.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);let o=t.default;var s,i,n,a=e.n(o);let r=t.default.SeriesRegistry;var l=e.n(r);let{series:{prototype:h,prototype:{pointClass:{prototype:d}}}}=l();!function(t){function e(){if(!this.hasDataLabels?.()&&this.nodes)for(let t of this.nodes)t.destroyElements({dataLabel:1})}function s(){return this.data=[].concat(this.points||[],this.nodes),h.destroy.apply(this,arguments)}function i(){this.nodes&&(this.nodes.forEach(t=>{t.destroy()}),this.nodes.length=0),h.setData.apply(this,arguments)}function n(t){let e=arguments,o=this.isNode?this.linksTo.concat(this.linksFrom):[this.fromNode,this.toNode];"select"!==t&&o.forEach(t=>{t&&t.series&&(d.setState.apply(t,e),!t.isNode&&(t.fromNode.graphic&&d.setState.apply(t.fromNode,e),t.toNode&&t.toNode.graphic&&d.setState.apply(t.toNode,e)))}),d.setState.apply(this,e)}function a(t,e,s,i){let n=this.series.options.nodes,a=this.series.options.data,r=a?.length||0,l=a?.[this.index];if(d.update.call(this,t,!this.isNode&&e,s,i),this.isNode){let t=(n||[]).reduce((t,e,o)=>this.id===e.id?o:t,-1),i=(0,o.merge)(n&&n[t]||{},a?.[this.index]||{});a&&(l?a[this.index]=l:a.length=r),n?t>=0?n[t]=i:n.push(i):this.series.options.nodes=[i],(0,o.pick)(e,!0)&&this.series.chart.redraw(s)}}t.compose=function(t,r){let l=t.prototype,h=r.prototype;return l.setNodeState=n,l.setState=n,l.update=a,h.destroy=s,h.setData=i,(0,o.addEvent)(r,"afterUpdate",e),r},t.createNode=function(t){let e=this.pointClass,s=(t,e)=>(0,o.find)(t,t=>t.id===e),i=s(this.nodes,t),n;if(!i){n=this.options.nodes&&s(this.options.nodes,t);let a=new e(this,(0,o.extend)({className:"highcharts-node",isNode:!0,id:t,y:1},n));a.linksTo=[],a.linksFrom=[],a.getSum=function(){let t=0,e=0;return a.linksTo.forEach(e=>{t+=e.weight||0}),a.linksFrom.forEach(t=>{e+=t.weight||0}),Math.max(t,e)},a.offset=function(t,e){let o=0;for(let s=0;s<a[e].length;s++){if(a[e][s]===t)return o;o+=a[e][s].weight}},a.hasShape=function(){let t=0;return a.linksTo.forEach(e=>{e.outgoing&&t++}),!a.linksTo.length||t!==a.linksTo.length},a.index=this.nodes.push(a)-1,i=a}return i.formatPrefix="node",i.name=i.name||i.options.id||"",i.mass=(0,o.pick)(i.options.mass,i.options.marker&&i.options.marker.radius,this.options.marker&&this.options.marker.radius,4),i},t.destroy=s,t.generatePoints=function(){let t=this.chart,e={};h.generatePoints.call(this),this.nodes||(this.nodes=[]),this.colorCounter=0,this.nodes.forEach(t=>{t.linksFrom.length=0,t.linksTo.length=0,t.level=t.options.level}),this.points.forEach(s=>{(0,o.defined)(s.from)&&(e[s.from]||(e[s.from]=this.createNode(s.from)),e[s.from].linksFrom.push(s),s.fromNode=e[s.from],t.styledMode?s.colorIndex=(0,o.pick)(s.options.colorIndex,e[s.from].colorIndex):s.color=s.options.color||e[s.from].color),(0,o.defined)(s.to)&&(e[s.to]||(e[s.to]=this.createNode(s.to)),e[s.to].linksTo.push(s),s.toNode=e[s.to]),s.name=s.name||s.id},this),this.nodeLookup=e},t.setNodeState=n,t.updateNode=a}(i||(i={}));let p=i,{seriesTypes:{sankey:{prototype:{pointClass:u}}}}=l();class c extends u{isValid(){return!0}}(0,o.extend)(c.prototype,{setState:p.setNodeState});var f=n||(n={});f.compose=function(t,e){return t.sankeyColumn=new m(t,e),t};class m{constructor(t,e){this.points=t,this.series=e}getTranslationFactor(t){let e=this.points,o=e.slice(),s=t.chart,i=t.options.minLinkWidth||0,n,a=0,r,l=(s.plotSizeY||0)-(t.options.borderWidth||0)-(e.length-1)*t.nodePadding;for(;e.length;){for(a=l/e.sankeyColumn.sum(),n=!1,r=e.length;r--;)e[r].getSum()*a<i&&(e.splice(r,1),l=Math.max(0,l-i),n=!0);if(!n)break}for(let t of(e.length=0,o))e.push(t);return a}top(t){let e=this.series,s=e.nodePadding,i=this.points.reduce((o,i)=>(o>0&&(o+=s),o+=Math.max(i.getSum()*t,e.options.minLinkWidth||0)),0);return(0,o.getAlignFactor)(e.options.nodeAlignment||"center")*((e.chart.plotSizeY||0)-i)}left(t){let e=this.series,o=e.chart,s=e.options.equalNodes,i=o.inverted?o.plotHeight:o.plotWidth,n=e.nodePadding,a=this.points.reduce((o,a)=>(o>0&&(o+=n),o+=s?i/a.series.nodes.length-n:Math.max(a.getSum()*t,e.options.minLinkWidth||0)),0);return((o.plotSizeX||0)-Math.round(a))/2}sum(){return this.points.reduce((t,e)=>t+e.getSum(),0)}offset(t,e){let s=this.points,i=this.series,n=i.nodePadding,a=0,r;if(i.is("organization")&&t.hangsFrom)return{absoluteTop:t.hangsFrom.nodeY};for(let l=0;l<s.length;l++){let h=s[l].getSum(),d=Math.max(h*e,i.options.minLinkWidth||0),p=t.options[i.chart.inverted?"offsetHorizontal":"offsetVertical"],u=t.options.offset||0;if(r=h?d+n:0,s[l]===t)return{relativeTop:a+((0,o.defined)(p)?(0,o.relativeLength)(p,d):(0,o.relativeLength)(u,r))};a+=r}}}f.SankeyColumnAdditions=m;let g=n,y=t.default.Series;var x=e.n(y);let k=t.default.SVGRenderer;var b=e.n(k);let L=t.default.SVGElement;var P=e.n(L);let{composed:S,deg2rad:v}=a();s=P(),(0,o.pushUnique)(S,"TextPath")&&((0,o.addEvent)(s,"afterGetBBox",function(t){let e=t.bBox,o=this.element?.querySelector("textPath");if(o){let t=[],{b:s,h:i}=this.renderer.fontMetrics(this.element),n=i-s,a=RegExp('(<tspan>|<tspan(?!\\sclass="highcharts-br")[^>]*>|<\\/tspan>)',"g"),r=o.innerHTML.replace(a,"").split(/<tspan class="highcharts-br"[^>]*>/),l=r.length,h=(t,e)=>{let{x:i,y:a}=e,r=(o.getRotationOfChar(t)-90)*v,l=Math.cos(r),h=Math.sin(r);return[[i-n*l,a-n*h],[i+s*l,a+s*h]]};for(let e=0,s=0;s<l;s++){let i=r[s].length;for(let n=0;n<i;n+=5)try{let i=e+n+s,[a,r]=h(i,o.getStartPositionOfChar(i));0===n?(t.push(r),t.push(a)):(0===s&&t.unshift(r),s===l-1&&t.push(a))}catch{break}e+=i-1;try{let i=e+s,n=o.getEndPositionOfChar(i),[a,r]=h(i,n);t.unshift(r),t.unshift(a)}catch{break}}t.length&&t.push(t[0].slice()),e.polygon=t}return e}),(0,o.addEvent)(s,"beforeAddingDataLabel",function(t){let e=t.labelOptions,o=t.point,s=e[o.formatPrefix+"TextPath"]||e.textPath;s&&!e.useHTML&&(this.setTextPath(o.getDataLabelPath?.(this)||o.graphic,s),o.dataLabelPath&&!s.enabled&&(o.dataLabelPath=o.dataLabelPath.destroy()))}),s.prototype.setTextPath=s.prototype.setTextPath??function(t,e){let s=this.renderer.url,i=this.text||this,n=i.textPath,{attributes:a,enabled:r}=(0,o.merge)({enabled:!0,attributes:{dy:-5,startOffset:"50%",textAnchor:"middle"}},e);if(t=t||n&&n.path,n?.undo(),t&&r){let e=(0,o.addEvent)(i,"afterModifyTree",e=>{if(t&&r){let n=t.attr("id");n||t.attr("id",n=(0,o.uniqueKey)());let r={x:0,y:0};(0,o.defined)(a.dx)&&(r.dx=a.dx,delete a.dx),(0,o.defined)(a.dy)&&(r.dy=a.dy,delete a.dy),i.attr(r),this.attr({transform:""}),this.box&&(this.box=this.box.destroy());let l=e.nodes.slice(0);e.nodes.length=0,e.nodes[0]={tagName:"textPath",attributes:(0,o.extend)(a,{"text-anchor":a.textAnchor,href:`${s}#${n}`}),children:l}}});i.textPath={path:t,undo:e}}else i.attr({dx:0,dy:0}),delete i.textPath;return this.added&&(i.textCache="",this.renderer.buildText(i)),this});let{prototype:{symbols:N}}=b(),{seriesTypes:{column:T,sankey:C}}=l();class M extends C{createNodeColumns(){let t=this,e=t.chart,s=g.compose([],t);return s.sankeyColumn.maxLength=e.inverted?e.plotHeight:e.plotWidth,s.sankeyColumn.getTranslationFactor=t=>{let o=s.slice(),i=this.options.minLinkWidth||0,n,a=0,r,l,h=0,d=1,p=0,u=(e.plotSizeX||0)-(t.options.marker&&t.options.marker.lineWidth||0)-(s.length-1)*t.nodePadding;for(;s.length;){for(a=u/s.sankeyColumn.sum(),n=!1,r=s.length;r--;){l=s[r].getSum()*a*d;let t=Math.min(e.plotHeight,e.plotWidth);l>t?d=Math.min(t/l,d):l<i&&(s.splice(r,1),u-=i,l=i,n=!0),p+=l*(1-d)/2,h=Math.max(h,l)}if(!n)break}return s.length=0,o.forEach(t=>{t.scale=d,s.push(t)}),s.sankeyColumn.maxRadius=h,s.sankeyColumn.scale=d,s.sankeyColumn.additionalSpace=p,a},s.sankeyColumn.offset=function(i,n){let a=i.series.options.equalNodes,r=t.nodePadding,l=Math.min(e.plotWidth,e.plotHeight,(s.sankeyColumn.maxLength||0)/t.nodes.length-r),h=s.sankeyColumn.additionalSpace||0,d;for(let e=0;e<s.length;e++){let p=s[e].getSum()*(s.sankeyColumn.scale||0),u=a?l:Math.max(p*n,t.options.minLinkWidth||0);if(d=p?u+r:0,s[e]===i)return{relativeLeft:h+(0,o.relativeLength)(i.options.offset||0,d)};h+=d}},t.nodes.forEach(function(t){t.column=0,s.push(t)}),[s]}translateLink(t){let e=t.fromNode,s=t.toNode,i=this.chart,n=this.translationFactor,a=t.options,r=this.options,l=(0,o.pick)(a.linkWeight,r.linkWeight,Math.max((t.weight||0)*n*e.scale,this.options.minLinkWidth||0)),h=t.series.options.centeredLinks,d=e.nodeY,p=(e,o)=>{let s=(e.offset(t,o)||0)*n;return Math.min(e.nodeX+s,e.nodeX+(e.shapeArgs&&e.shapeArgs.height||0)-l)},u=h?e.nodeX+((e.shapeArgs.height||0)-l)/2:p(e,"linksFrom"),c=h?s.nodeX+((s.shapeArgs.height||0)-l)/2:p(s,"linksTo"),f=d;u>c&&([u,c]=[c,u]),r.reversed&&([u,c]=[c,u],f=(i.plotSizeY||0)-f),t.shapeType="path",t.linkBase=[u,u+l,c,c+l];let m=(c+l-u)/Math.abs(c+l-u)*(0,o.pick)(r.linkRadius,Math.min(Math.abs(c+l-u)/2,e.nodeY-Math.abs(l)));t.shapeArgs={d:[["M",u,f],["A",(c+l-u)/2,m,0,0,1,c+l,f],["L",c,f],["A",(c-u-l)/2,m-l,0,0,0,u+l,f],["Z"]]},t.dlBox={x:u+(c-u)/2,y:f-m,height:l,width:0},t.tooltipPos=i.inverted?[(i.plotSizeY||0)-t.dlBox.y-l/2,(i.plotSizeX||0)-t.dlBox.x]:[t.dlBox.x,t.dlBox.y+l/2],t.y=t.plotY=1,t.x=t.plotX=1,t.color||(t.color=e.color)}translateNode(t,e){let s=this.translationFactor,i=this.chart,n=i.inverted?i.plotWidth:i.plotHeight,a=this.options,r=Math.min(i.plotWidth,i.plotHeight,n/t.series.nodes.length-this.nodePadding),l=t.getSum()*(e.sankeyColumn.scale||0),h=a.equalNodes?r:Math.max(l*s,this.options.minLinkWidth||0),d=a.marker?.lineWidth||0,p=e.sankeyColumn.offset(t,s),u=(0,o.crisp)((0,o.pick)(p&&p.absoluteLeft,(e.sankeyColumn.left(s)||0)+(p&&p.relativeLeft||0)),d),c=(0,o.merge)(a.marker,t.options.marker),f=c.symbol,m=c.radius,g=parseInt(a.offset??"100",10)*((i.inverted?i.plotWidth:i.plotHeight)-((0,o.crisp)(this.colDistance*(t.column||0)+(c.lineWidth||0)/2,d)+(e.sankeyColumn.scale||0)*(e.sankeyColumn.maxRadius||0)/2))/100;if(t.sum=l,l){t.nodeX=u,t.nodeY=g;let e=t.options.width||a.width||h,o=t.options.height||a.height||h,s=g;a.reversed&&(s=(i.plotSizeY||0)-g,i.inverted&&(s=(i.plotSizeY||0)-g)),this.mapOptionsToLevel&&(t.dlOptions={...C.getDLOptions({level:this.mapOptionsToLevel[t.level],optionsPoint:t.options}),zIndex:void 0},delete t.dlOptions.zIndex),t.plotX=1,t.plotY=1,t.tooltipPos=i.inverted?[(i.plotSizeY||0)-s-o/2,(i.plotSizeX||0)-u-e/2]:[u+e/2,s+o/2],t.shapeType="path",t.shapeArgs={d:N[f||"circle"](u,s-(m||o)/2,m||e,m||o),width:m||e,height:m||o},t.dlBox={x:u+e/2,y:s,height:0,width:0}}else t.dlOptions={enabled:!1}}drawDataLabels(){if(this.options.dataLabels){let t=this.options.dataLabels.textPath;T.prototype.drawDataLabels.call(this,this.nodes),this.options.dataLabels.textPath=this.options.dataLabels.linkTextPath,T.prototype.drawDataLabels.call(this,this.data),this.options.dataLabels.textPath=t}}pointAttribs(t,e){if(t&&t.isNode){let{...t}=x().prototype.pointAttribs.apply(this,arguments);return t}return super.pointAttribs.apply(this,arguments)}markerAttribs(t){return t.isNode?super.markerAttribs.apply(this,arguments):{}}}M.defaultOptions=(0,o.merge)(C.defaultOptions,{centeredLinks:!1,equalNodes:!1,dataLabels:{linkTextPath:{attributes:{startOffset:"25%"}}},marker:{fillOpacity:1,lineWidth:0,states:{},symbol:"circle"},offset:"100%",reversed:!1}),(0,o.extend)(M.prototype,{orderNodes:!1}),M.prototype.pointClass=c,l().registerSeriesType("arcdiagram",M);let W=a();export{W as default};