1

I am implementing a Sankey charts using Highcharts where I need to display each nodes in specific symbol. I want to implement marker symbol feature for my Sankey graph.

I tried using marker.symbol which is not working.

marker: {
  symbol: 'triangle'
}

Is there a way to implement custom symbols for Sankey graph? Also is there a way where I can control the width of links between each nodes? All my nodes have same weight, hence I want a way to fix my width.

Guru
  • 13
  • 5

1 Answers1

0

Highcharts does not provide options that will allow to modify the marker symbol and the link width for sankey chart type, so it is not possible by default.

Workaround

  • To modify the links width, set scale and translate attributes.
  • To change the markers, use Highcharts.SVGRenderer and replace default rects by triangles.

    chart: {
        height: 200,
        events: {
            load: function() {
                var points = this.series[0].points,
                    fromNodeBBox,
                    toNodeBBox,
                    linkBBox;
    
                points.forEach(function(p) {
                    fromNodeBBox = p.fromNode.graphic.getBBox();
                    toNodeBBox = p.toNode.graphic.getBBox();
    
                    this.renderer.symbol(
                        'triangle',
                        fromNodeBBox.x + this.plotLeft + 10,
                        fromNodeBBox.y + this.plotTop,
                        fromNodeBBox.width,
                        fromNodeBBox.height
                    ).attr({
                        fill: p.fromNode.color
                    }).add();
    
                    this.renderer.symbol(
                        'triangle',
                        toNodeBBox.x + this.plotLeft - 10,
                        toNodeBBox.y + this.plotTop,
                        toNodeBBox.width,
                        toNodeBBox.height
                    ).attr({
                        fill: p.toNode.color,
                        zIndex: 3
                    }).add();
    
    
                    linkBBox = p.graphic.getBBox();
                    p.graphic.attr({
                        transform: 'scale(1 0.5) translate(0 ' + (linkBBox.y + fromNodeBBox.height / 2) + ')'
                    });
    
                    p.fromNode.graphic.destroy();
                    p.toNode.graphic.destroy();
                }, this);
            }
        }
    }
    

Live demo: https://jsfiddle.net/BlackLabel/f4u03qvd/

API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#symbol

ppotaczek
  • 36,341
  • 2
  • 14
  • 24
  • Thanks ppotaczek !!. This works great only when I have one level of from node and two nodes. but my app has multiple levels of from node and to nodes, something like ['A', 'B', 1], ['A', 'C', 1], ['C', 'D', 1], ['C', 'E', 1] In this case, I get an error as below. Any idea on how to resolve this? Uncaught TypeError: Cannot read property 'cache' of undefined at a.SVGElement.getBBox (highcharts.src.js:4787) at a.Chart. ((index):76) at Array.forEach () at a.Chart.load ((index):75) at highcharts.src.js:2624 at Array.forEach – Guru Feb 15 '19 at 05:14
  • Hi Guru, Yes, you have to adapt this solution to other cases, for example: https://jsfiddle.net/BlackLabel/gpdhrt85/ – ppotaczek Feb 15 '19 at 09:04
  • Thanks ppotaczek for your help. I will adapt thia as per my requirement. This helped a lot!! – Guru Feb 18 '19 at 06:27
  • I want to make all links with the same small width - 1-1.5 mm. I want to add arrows to the end of these lines. Is that possible? – Mark Mar 19 '22 at 17:13
  • Hi @Mark, Please create a new question with `highcharts` tag. – ppotaczek Mar 21 '22 at 13:59