stacked bar chart with overlapping bars C3js

五迷三道 提交于 2019-12-12 03:07:02

问题


Good day.

I'm trying to create a bar chart using C3.js that looks like the following:

I've tried stacked bar chart, but the problem is that I can't make each bar with different width, and also I can't make them overlap (be in top of each other).

Any help in getting to do it like the image above?

Thanks

UPDATE 1:

after trying couple of ideas, I ended up with this:

var chart = c3.generate({
data: {
    columns: [
      ['result1', null],
      ['result2', null],
      ['data1', -30],
      ['data2', -130],
      ['data3', -230],
      ['data4', -130],
      ['data5', -30],
      ['empty',''],
      ['data11', -30],
      ['data22', -130],
      ['data33', -230],
      ['data44', -130],
      ['data55', -30]
    ],

    type: 'bar',

    colors: {
      result1: '#c3c8d4',
      data1: '#c3c8d4',
      data2: '#c3c8d4',
      data3: '#c3c8d4',
      data4: '#c3c8d4',
      data5: '#c3c8d4',

      result2: '#3c9fbf',
      data11: '#3c9fbf',
      data22: '#3c9fbf',
      data33: '#3c9fbf',
      data44: '#3c9fbf',
      data55: '#3c9fbf',
    },
},
axis: {
    y: {
      tick: {
        format: function(d) {
          return (d >= 0) ? d : d * -1;
        }
      },
    }
},
bar: {
    width: {
      ratio: 0.1
    }
},
tooltip: {
    format: {
      value: function(value, ratio, id) {
        return;
      }
    }
}
});


d3.select('.c3-legend-item-result1').on('mouseover', function(id) {
    var tmparr = [];
    tmparr.push(id);
    for (var i = 0; i < 5; i++)
        tmparr.push('data' + (i + 1));
    chart.focus(tmparr);
  })
  .on('mouseout', function(id) {
    chart.revert();
  })
  .on('click', function(id) {
    var tmparr = [];
    for (var i = 0; i < 5; i++)
        tmparr.push('data' + (i + 1));
    chart.toggle(tmparr);
  });

d3.select('.c3-legend-item-result2').on('mouseover', function(id) {
    var tmparr = [];
    tmparr.push(id);
    for (var i = 0; i < 5; i++)
        tmparr.push('data' + (i + 1) + (i + 1));
    chart.focus(tmparr);
  })
  .on('mouseout', function(id) {
    chart.revert();
  })
  .on('click', function(id) {
    var tmparr = [];
    for (var i = 0; i < 5; i++)
        tmparr.push('data' + (i + 1) + (i + 1));
    chart.toggle(tmparr);
  });

JSFiddle: http://jsfiddle.net/h2ndL9cb/

but I think it's too much code, any other ideas?

Thanks


回答1:


You could define your chart data as such (see below). After you have your data, you can transform and hide the legend items.

The transformed data can be merged, using a library such as lodash, with the c3js object.

Of course, this does not solve your issue entirely, but this should give you an idea of how to transform your data to get the desired result.

var chartData = {
  data : {
    result1: [-30, -130, -230, -130, -30],
    result2: [-30, -130, -230, -130, -30]
  },
  colors: {
    result1: '#c3c8d4',
    result2: '#3c9fbf'
  },
};

function transformData(data) {
  var data_columns = [];
  var data_colors = {};
  var legend_hide = ['empty'];
  var keys = Object.keys(data.data);

  for (var k = 0; k < keys.length; k++) {
    var key = keys[k];
    var values = data.data[key];

    data_columns.splice(k, 0, [key, null]);
    data_colors[key] = data.colors[key];

    for (var i = 0; i < values.length; i++) {
      var value_key = key + '_' + k + '_' + i

      data_columns.push([value_key, values[i]]);
      data_colors[value_key] = data.colors[key];
      legend_hide.push(value_key);
    }
    if (k < keys.length - 1) {
      data_columns.push(['empty', '']);
    }
  }

  return {
    data : {
      columns : data_columns,
      colors : data_colors
    },
    legend : {
      hide : legend_hide
    }
  };
}

var chart = c3.generate(_.merge({
  data : {
    type : 'bar'
  },
  axis: {
    y: {
      tick: {
        format: function(d) {
          return (d >= 0) ? d : d * -1;
        }
      },
    }
  },
  bar: {
    width: {
      ratio: 0.1
    }
  },
  tooltip: {
    format: {
      value: function(value, ratio, id) {
        return;
      }
    }
  }
}, transformData(chartData))); // Transform and merge data...
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css">

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.10/d3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>

<div id="chart"></div>


来源:https://stackoverflow.com/questions/34121771/stacked-bar-chart-with-overlapping-bars-c3js

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