Search code examples
javascripthighchartsrickshaw

How to display datapoint labels / values in Rickshaw graph visualizations?


We're phasing out the Highcharts javascript visualization lib from our interactive statistics research application. It was already replaced with Rickshaw. Just now a new request came in: One certain use case has the graph display with the measurements displayed in the graph directly. This has been the case while using Highcharts (which has an option for that; called dataLabelsActivated). That should still be the case when using Rickshaw. I haven't yet found an option to make it do that. Any ideas?

How it used to display with Highcharts - highlighted in red are the measurements that should be there when using Rickshaw:

How it used to display with Highcharts

How it currently display with Rickshaw:

How it currently display with Rickshaw


Solution

  • Apparently rickshaw doesn't support this natively. I might've done that by extending rickshar through the d3 library it is based upon (which seems to be able to do what I intended to achieve, according to the examples on its website). However, I ended up with a simple solution - added the data labels as divs manually, dependent on the distance of each datapoint from the top left corner of the graph element. Below code searches the data attribute of the graph for the data to display in labels using the color of the datapoint as it is the sole item to match a datapoint with the information in the data attribute.

      $(".pointMarker").each(function( index ) {
        var percentage = 0;
        var currentMarkerColor = self.rgb2hex($( this ).css("border-top-color"));
        self.graph.series.forEach(function(series) {
          if(currentMarkerColor === series.color) {
            if ( !/undef/i.test(typeof series.data[index])) {
              percentage =  parseFloat(series.data[index].y).toFixed(2);
            }
            //end loop
            return false;
          }
        });
        if (percentage > 0) {
          var totalHeight = $( this ).parent().height();
          var distanceTop = $( this ).css("top").replace(/[^-\d\.]/g, '') ;
          //display data
          $( this ).parent().append( "<div class='dataLabel' style='top:"+(parseInt($(this).css('top'), 10)-5)+"px;left:"+(parseInt($(this).css('left'), 10)-9)+"px;height:100px;width:100px;'>"+percentage+"</div>" );
        }
      });
    

    and

    this.rgb2hex = function (rgb){
        rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
        return "#" +
             ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
             ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
             ("0" + parseInt(rgb[3],10).toString(16)).slice(-2);
    }