Sankey diagram. Help needed to execute javascript in HABPanel custom widget

Plotly makes unsafe evaluations in its code, this is blocked by the restrictive CSP put in place in HABPanel’s code (which you cannot change unless you fork it). See: https://github.com/plotly/plotly.js/issues/897

But you can use another library like ECharts: https://www.echartsjs.com/examples/en/#chart-type-sankey

Download echarts-en.min.js from https://github.com/apache/incubator-echarts/tree/4.5.0/dist (actually https://raw.githubusercontent.com/apache/incubator-echarts/4.5.0/dist/echarts-en.min.js).
Then make an AngularJS directive like this:

angular
  .module('app.widgets')
  .directive('sankeyDiagram', ['OHService', function (OHService) {
    return {
      restrict: 'E',
      scope: {
        // optionally add attributes here
        // orientation: '=',
        // ...
      },
      link: function (scope, elem, attrs) {
        var myChart = echarts.init(elem[0].parentElement, 'dark');
        // mainly taken from https://www.echartsjs.com/examples/en/editor.html?c=sankey-simple
        myChart.setOption(option = {
          color: [
            '#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'
          ],
          tooltip: {
            trigger: 'item',
            triggerOn: 'mousemove'
          },
          animation: false,
          series: {
            type: 'sankey',
            layout: 'none',
            data: [{
              name: 'a'
            }, {
              name: 'b'
            }, {
              name: 'a1'
            }, {
              name: 'a2'
            }, {
              name: 'b1'
            }, {
              name: 'c'
            }],
            links: [{
              source: 'a',
              target: 'a1',
              value: 5
            }, {
              source: 'a',
              target: 'a2',
              value: 3
            }, {
              source: 'b',
              target: 'b1',
              value: 8
            }, {
              source: 'a',
              target: 'b1',
              value: 3
            }, {
              source: 'b1',
              target: 'a1',
              value: 1
            }, {
              source: 'b1',
              target: 'c',
              value: 2
            }]
          }
        });
      }
    };
  }]);

Your template will then be:

<div style="width:800px;height:600px"
     oc-lazy-load="{ serie: true, files: ['/static/cps/echarts-en.min.js', '/static/cps/cp.js']}">
  <sankey-diagram></sankey-diagram>
</div>

note the serie: true ocLazyLoad option to load the JS files in a sequence (first ECharts then your code).

If you can have this working you’re on the right path, look in the ECharts docs to customize options and search here on how to use the OHService injected in the directive to retrieve data from your items.

1 Like