0
votes

I am currently trying to display a bar chart using a flot js with the stack plugin. The data is however not stacking properly and it also overlaps. The dataset is quite large and uses linux time stamp to match an array of time.

I have included both code and a js fiddle.

Here is my code:

jQuery(document).ready(function() {
  var $dataMonths = [
    [1535752800, 'Sep (2018)'],
    [1538344800, 'Okt (2018)'],
    [1541026800, 'Nov (2018)'],
    [1543618800, 'Dec (2018)'],
    [1546297200, 'Jan (2019)'],
    [1548975600, 'Feb (2019)'],
    [1551394800, 'Mars (2019)'],
    [1554069600, 'Apr (2019)'],
    [1556661600, 'Maj (2019)'],
    [1559340000, 'Jun (2019)'],
    [1561932000, 'Jul (2019)'],
    [1564610400, 'Aug (2019)'],
    [1567288800, 'Sep (2019)'],
    [1569880800, 'Okt (2019)'],
  ];

  /** BAR CHART */
  var dataset = [{
    label: "id8",
    data: [
      [1569880800, 210]
    ],
    stack: true
  }, {
    label: "id3",
    data: [
      [1569880800, 800]
    ],
    stack: true
  }, {
    label: "id4",
    data: [
      [1569880800, 800]
    ],
    stack: true
  }, {
    label: "id16",
    data: [
      [1569880800, 300],
      [1575154800, 300]
    ],
    stack: true
  }, {
    label: "id12",
    data: [
      [1569880800, 1834],
      [1572562800, 185],
      [1575154800, 75]
    ],
    stack: true
  }, {
    label: "id9",
    data: [
      [1569880800, 150],
      [1572562800, 450],
      [1575154800, 900],
      [1577833200, 750]
    ],
    stack: true
  }, {
    label: "id5",
    data: [
      [1569880800, 400],
      [1577833200, 300]
    ],
    stack: true
  }, {
    label: "id17",
    data: [
      [1572562800, 300]
    ],
    stack: true
  }, {
    label: "id13",
    data: [
      [1572562800, 300],
      [1575154800, 300]
    ],
    stack: true
  }, {
    label: "id15",
    data: [
      [1572562800, 350],
      [1575154800, 1550]
    ],
    stack: true
  }, {
    label: "id7",
    data: [
      [1572562800, 338]
    ],
    stack: true
  }, {
    label: "id11",
    data: [
      [1572562800, 235]
    ],
    stack: true
  }, {
    label: "id10/",
    data: [
      [1572562800, 150]
    ],
    stack: true
  }, {
    label: "id14",
    data: [
      [1572562800, 1450],
      [1575154800, 1200]
    ],
    stack: true
  }, {
    label: "id2",
    data: [
      [1575154800, 600]
    ],
    stack: true
  }, {
    label: "id6",
    data: [
      [1575154800, 300]
    ],
    stack: true
  }, {
    label: "id18",
    data: [
      [1575154800, 300],
      [1577833200, 300]
    ],
    stack: true
  }, {
    label: "id1",
    data: [
      [1575154800, 300],
      [1577833200, 1200]
    ],
    stack: true
  }, {
    label: "null",
    data: [
      [1577833200, 950],
      [1580511600, 4905],
      [1583017200, 1350]
    ],
    stack: true
  }];

  var linkTotalEearnings = [];
  linkTotalEearnings["null"] = "7205";
  linkTotalEearnings["id1"] = "1500";
  linkTotalEearnings["id2"] = "600";
  linkTotalEearnings["id3"] = "800";
  linkTotalEearnings["id4"] = "800";
  linkTotalEearnings["id5"] = "700";
  linkTotalEearnings["id6"] = "300";
  linkTotalEearnings["id7"] = "338";
  linkTotalEearnings["id8"] = "210";
  linkTotalEearnings["id9"] = "2250";
  linkTotalEearnings["id10/"] = "150";
  linkTotalEearnings["id11"] = "235";
  linkTotalEearnings["id12"] = "2094";
  linkTotalEearnings["id13"] = "600";
  linkTotalEearnings["id14"] = "2650";
  linkTotalEearnings["id15"] = "1900";
  linkTotalEearnings["id16"] = "600";
  linkTotalEearnings["id17"] = "300";
  linkTotalEearnings["id18"] = "600";

  var $barChart = jQuery("#link-url-sales-graph");

  $.plot($barChart, dataset, {
    series: {
      bars: {
        show: true,
        align: "center",
        barWidth: 1000000,
        lineWidth: 0,
      }
    },
    xaxis: {
      //mode: "categories",
      showTicks: true,
      gridLines: false,
      ticks: $dataMonths,
      tickLength: 1,
    },
    grid: {
      hoverable: true,
      borderWidth: 0,
    },
    yaxis: {
      allowDecimals: false,
      gridLines: false,
      tickColor: '#f5f5f5'
    },
    legend: {
      show: true,
      container: jQuery("#link-url-sales-legend-container"),
      labelFormatter: function(label, series) {
        // series is the series object for the label
        return '<span>' + label + ' (<strong>' + linkTotalEearnings[label] + ' units</strong>)</span>';
      },
      sorted: function(a, b) {
        var aVal = parseInt(a.label.substring(
          a.label.lastIndexOf("(<strong>") + 9,
          a.label.lastIndexOf(" units</strong>)")
        ));

        var bVal = parseInt(b.label.substring(
          b.label.lastIndexOf("(<strong>") + 9,
          b.label.lastIndexOf(" units</strong>)")
        ));

        return aVal == bVal ? 0 : (
          aVal > bVal ? -1 : 1
        );
      },
      noColumns: 1,
      backgroundOpacity: 0
    }
  });

  var previousPoint = null,
    ttlabel = null;
  $barChart.bind('plothover', function(event, pos, item) {
    if (item) {
      //console.log(item);
      if (previousPoint !== item.dataIndex) {
        previousPoint = item.dataIndex;
        console.log(item);
        jQuery('.js-flot-tooltip').remove();

        var x = item.datapoint[0],
          y = item.datapoint[1];

        var label = item.series != '' ? item.series.label : '';
        var amount = item.datapoint[1] - item.datapoint[2];

        jQuery('<div class="js-flot-tooltip flot-tooltip">' + label + ' (' + amount + ' units)</div>')
          .css({
            top: item.pageY - 45,
            left: item.pageX + 5
          }).appendTo("body").show();
      }
    } else {
      jQuery('.js-flot-tooltip').remove();
      previousPoint = null;
    }
  });
});
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.stack.min.js"></script>

<h1>
  Chart
</h1>
<div id="link-url-sales-graph" style="height: 500px;"></div>
<div id="link-url-sales-legend-container" class="mt-2"></div>

Here is my jsfiddle: https://jsfiddle.net/ethor/dgp618kb/5/

1

1 Answers

0
votes

You need to put a value for every timestamp in every dataseries (fill with zeros). Like this:

var dataset = [{
  label: "id8",
  data: [
    [1569880800, 210],
    [1572562800, 0],
    [1575154800, 0],
    [1577833200, 0]
  ],
  stack: true
},
{
  label: "id3",
  data: [
    [1569880800, 800],
    [1572562800, 0],
    [1575154800, 0],
    [1577833200, 0]
  ],
  stack: true
},
{
...

This is because the starting positions for the stacked bars are calculated like 300 + 0 + 400 + 0 + 300 + 300 + ... If you don't have all values you get calculations like 300 + undefined + 400 + undefined + ... which give false positions for the bars.

See this updated fiddle for a working example (I removed some data to make it easier to fill up all missing values).