Black Lives Matter. Please consider donating to Black Girls Code today.

Quick implement of a variation of radius in pie charts

Hello there

I am interested in using a special kind of pie chart which actually looks a bit like the wind rose chart : the angle of the different slices is the same, but the area still changes, which is made possible by changing the radius of each slice.

I have tried a quick and dirty implementation because there doesn’t seem to be a way to do it via the options list.

What I do is basically scaling the path elements after the chart has been rendered (I told you it was dirty). As you can see in the images bellow, there is an alignment issue


Here is the code. You will notice I have two problems :

  • the SVG paths are not drawn in the same order as the data list, so I can’t find a way to identify which slice in the DOM corresponds to which line in my data without having to add a textinfo containing my label.

  • I don’t know how to properly set the origin of the scale transformation. Interestingly, using the CSS rule “transform-origin: center;” seems to magically do something close to what I want, but there are visible gaps after scaling.

    function customChart(table) {
    var data = {
    values: table.map(function(row) {
    return 1;
    }), // we set everything to 1 so that the angle is the same for every slice
    labels: table.map(function(row) {
    return row[0];
    }),
    showlegend: false,
    textposition: “inside”,
    textinfo: “label”,
    hoverinfo: “none”,
    type: “pie”
    };

      var fragment = document.createElement("div");
      Plotly.newPlot(fragment, [data]);
    
      var max = Math.max.apply(Math, table.extractCol("Values"));
      var min = 0.2;
    
      forEach(fragment.querySelectorAll("g.slice"), function(slice) {
          var label = slice.querySelector("text.slicetext").textContent;
          var val = table.getCell("Values", label);
          var scale = val / max
          slice.firstChild.style.transform = "scale(" + scale + ", " + scale + ")";
          slice.firstChild.style.transformOrigin = "center";
      });
      return fragment;
    

    }

I have left some code related to my data library, you can ignore it.

Swapping the angle for the radius is probably very easy but finding the right line in the source code is a bit paiful.
Thanks for your help !

Geoffrey