Flotchart stacked bar total label

▼魔方 西西 提交于 2020-01-05 08:45:21

问题


I am using Flotcharts to create a stacked bar chart to show breakdown of values. I have this working so that once I hover over the stack it will show a tool tip with the value for that stack in it (you can see this in the second column).

What I need is at the top of all the stacks that it shows a label of the total value.

Something like High Charts Stacked Column.

You can see my code below. I loop through the data (using Smarty) and set it there.

// set the data
var data = [
    {
        label: 'Tenant',
        data: [
            {foreach $metrics.rent_applied_by_month as $rent_applied}
                [{$rent_applied@index}, {$rent_applied.tenant_value|number_format:2:'.':''}],
            {/foreach}
        ],
        color: '#008000'
    },
    {
        label: 'Benefit',
        data: [
            {foreach $metrics.rent_applied_by_month as $rent_applied}
                [{$rent_applied@index}, {$rent_applied.benefit_value|number_format:2:'.':''}],
            {/foreach}
        ],
        color: '#0000ff'
    }
];

// set the xasis labels
var ticks = [
    {foreach $metrics.rent_applied_by_month as $rent_applied}
        [{$rent_applied@index}, '{$rent_applied.period}'],
    {/foreach}
];

// chart options
var options = {
    series: {
        stack: 0,
        bars: {
            show: true,
            align: "center",
            barWidth: 0.6,
            fill: .75,
        }
    },
    xaxis: {
        ticks: ticks,
        tickLength: 1
    },
    grid: {
        hoverable: true,
        clickable: true,
        borderWidth: {
            top: 0,
            right: 0,
            bottom: 1,
            left: 1
        },
        borderColor: {
            top: "#e5e5e5",
            right: "#e5e5e5",
            bottom: "#a5b2c0",
            left: "#a5b2c0"
        }
    },
    legend: {
        show: true,
        noColumns: 2,
        position: "nw",
        margin: [10, 0],
        labelBoxBorderColor: null
    }
};

$.plot("#rent_applied", data, options);

回答1:


You'll need to loop through each of the bars in each stack to get the total value of all bars in each stack. With that total value in hand, you can pass it into flot's plot.pointOffset() method to get the position of the top of the stacked bars.

The code below has a sample method to get all of the values of a stack of bars, then uses the plot.pointOffset() to append a div showing the value on top of the bar.

$(function() {
  var data = [{
    data: [ [0, 21.51], [1, 32.50], [2, 47.14], [3, 10] ],
    stack: 0,
    label: 'Bottom'
  }, {
    data: [ [0, 37.77], [1, 24.65], [2, 7.67], [4, 15]],
    stack: 0,
    label: 'Top'
  }];

  var options = {
    series: {
      bars: {
        show: true,
        barWidth: .5,
        align: "center"
      },
      points: { show: false }
    }
  };

  var plot = $.plot($('#graph'), data, options);

  displayBarValues();

  // display values on top of bars  
  function displayBarValues() {
    var plotData = plot.getData();
    var xValueToStackValueMapping = [];

    // loop through each data series
    for (var i = 0; i < plotData.length; i++) {
      var series = plotData[i];

      // loop through each data point in the series
      for (var j = 0; j < series.data.length; j++) {
        var value = series.data[j];

        // if the x axis value is not in the mapping, add it.
        if (!xValueExistsInMapping(xValueToStackValueMapping, value[0])) {
          xValueToStackValueMapping.push([value[0], 0]);
        }

        // add the value of the bar to the x value mapping
        addValueToMapping(xValueToStackValueMapping, value[0], value[1]);
      }
    }

    // loop through each of our stacked values and place them on the bar chart
    $.each(xValueToStackValueMapping, function(i, value) {
      // find the offset of the top left of the bar
      var leftoffset = plot.pointOffset({ x: value[0] - .5, y: value[1] });

      // find the offset of the top right of the bar (our bar width is .5)
      var rightoffset = plot.pointOffset({ x: value[0] + .5, y: value[1] });

      $('<div class="data-point-value">' + value[1] + '</div>').css({
        left: leftoffset.left,
        top: leftoffset.top - 14,
        width: rightoffset.left - leftoffset.left,
        textAlign: 'center'
      }).appendTo(plot.getPlaceholder());
    });


  }

  function xValueExistsInMapping(mapping, value) {
    for (var i = 0; i < mapping.length; i++) {
      if (mapping[i][0] !== undefined && mapping[i][0] === value) {
        return true;
      }
    }
    return false;
  }

  function addValueToMapping(mapping, xValue, yValue) {
    for (var i = 0; i < mapping.length; i++) {
      if (mapping[i][0] === xValue) {
        mapping[i][1] = mapping[i][1] + yValue;
      }
    }
  }
});
#graph {
  margin: 0 auto;
  text-align: center;
  width: 600px;
  height: 400px;
}

.data-point-value {
  position: absolute;
  white-space: nowrap;
  font-size: 11px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.js"></script>
<script src="https://rawgit.com/flot/flot/master/jquery.flot.stack.js"></script>
<div id="graph"></div>


来源:https://stackoverflow.com/questions/40528551/flotchart-stacked-bar-total-label

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!