【问题标题】:How to create vertically grouped bar chart in d3.js using json data?如何使用 json 数据在 d3.js 中创建垂直分组的条形图?
【发布时间】:2016-03-22 05:11:39
【问题描述】:

在一个网络应用程序中,我应该使用 d3.js 使用 json 数据创建一个垂直分组的条形图。以前我使用以下代码创建了一个水平分组条。谁能帮我吗?提前致谢。

var data = {
  labels: [
    'resilience', 'maintainability', 'accessibility',
    'uptime', 'functionality', 'impact'
  ],
  series: [
    {
      label: '2012',
      values: [4, 8, 15, 16, 23, 42]
    },
    {
      label: '2013',
      values: [12, 43, 22, 11, 73, 25]
    },
    {
      label: '2014',
      values: [31, 28, 14, 8, 15, 21]
    },]
};

var chartWidth       = 300,
    barHeight        = 20,
    groupHeight      = barHeight * data.series.length,
    gapBetweenGroups = 10,
    spaceForLabels   = 150,
    spaceForLegend   = 150;

// Zip the series data together (first values, second values, etc.)
var zippedData = [];
for (var i=0; i<data.labels.length; i++) {
  for (var j=0; j<data.series.length; j++) {
    zippedData.push(data.series[j].values[i]);
  }
}

// Color scale
var color = d3.scale.category20();
var chartHeight = barHeight * zippedData.length + gapBetweenGroups * data.labels.length;

var x = d3.scale.linear()
    .domain([0, d3.max(zippedData)])
    .range([0, chartWidth]);

var y = d3.scale.linear()
    .range([chartHeight + gapBetweenGroups, 0]);

var yAxis = d3.svg.axis()
    .scale(y)
    .tickFormat('')
    .tickSize(0)
    .orient("left");

// Specify the chart area and dimensions
var chart = d3.select(".chart")
    .attr("width", spaceForLabels + chartWidth + spaceForLegend)
    .attr("height", chartHeight);

// Create bars
var bar = chart.selectAll("g")
    .data(zippedData)
    .enter().append("g")
    .attr("transform", function(d, i) {
      return "translate(" + spaceForLabels + "," + (i * barHeight + gapBetweenGroups * (0.5 + Math.floor(i/data.series.length))) + ")";
    });

// Create rectangles of the correct width
bar.append("rect")
    .attr("fill", function(d,i) { return color(i % data.series.length); })
    .attr("class", "bar")
    .attr("width", x)
    .attr("height", barHeight - 1);

// Add text label in bar
bar.append("text")
    .attr("x", function(d) { return x(d) - 3; })
    .attr("y", barHeight / 2)
    .attr("fill", "red")
    .attr("dy", ".35em")
    .text(function(d) { return d; });

// Draw labels
bar.append("text")
    .attr("class", "label")
    .attr("x", function(d) { return - 10; })
    .attr("y", groupHeight / 2)
    .attr("dy", ".35em")
    .text(function(d,i) {
      if (i % data.series.length === 0)
        return data.labels[Math.floor(i/data.series.length)];
      else
        return ""});

chart.append("g")
      .attr("class", "y axis")
      .attr("transform", "translate(" + spaceForLabels + ", " + -gapBetweenGroups/2 + ")")
      .call(yAxis);

// Draw legend
var legendRectSize = 18,
    legendSpacing  = 4;

var legend = chart.selectAll('.legend')
    .data(data.series)
    .enter()
    .append('g')
    .attr('transform', function (d, i) {
        var height = legendRectSize + legendSpacing;
        var offset = -gapBetweenGroups/2;
        var horz = spaceForLabels + chartWidth + 40 - legendRectSize;
        var vert = i * height - offset;
        return 'translate(' + horz + ',' + vert + ')';
    });

legend.append('rect')
    .attr('width', legendRectSize)
    .attr('height', legendRectSize)
    .style('fill', function (d, i) { return color(i); })
    .style('stroke', function (d, i) { return color(i); });

legend.append('text')
    .attr('class', 'legend')
    .attr('x', legendRectSize + legendSpacing)
    .attr('y', legendRectSize - legendSpacing)
    .text(function (d) { return d.label; });

【问题讨论】:

  • 您是否使用顶部声明的数据bar-data.csvdata 数组作为要在此图表中显示的数据?
  • 不,我没有使用 bar-data.csv。我正在使用数据数组。
  • 您分享的上述代码 sn-p 需要bar-data.csv。请将其编辑为水平条形图的工作示例。
  • 我在以下行中声明数据变量。 var data=[ {"Upazila":"Tangail","Progress":95.23}, {"Upazila":"Barisal","Progress":85.23}, {"Upazila":"Habiganj","Progress":75.23} ];是bar-data.csv格式吗?
  • 抱歉我在帖子中犯的错误。我在这里粘贴了错误的代码 sn-p。我刚刚编辑了它。很抱歉给您带来不便。

标签: javascript d3.js nvd3.js


【解决方案1】:

经过不断的挖掘,我找到了正确的方法。感谢 Mike Bostock 在here 中提供的示例。在here,您还可以找到该示例的详细讨论。感谢您的支持:)

    
    var margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;
    
    var x0 = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);
    
    var x1 = d3.scale.ordinal();
    
    
    var y = d3.scale.linear()
    .range([height, 0]);
    
    
    var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
    
    
    var xAxis = d3.svg.axis()
    .scale(x0)
    .orient("bottom");
    
    var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickFormat(d3.format(".2s"));
    
    //console.log(margin.left);
    var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    /*Our json object is [{letter: "A", frequency: .08167,depth:.32},{letter: "B", frequency: .01492,depth:.69}]
    
    To use csv file you just need to follow the link I provided
    */
    
    var data = [
  {letter: "A", frequency: .08167,depth:.32},
  {letter: "B", frequency: .01492,depth:.69}
];
    var groupNames=d3.keys(data[0]).filter(function(key){return key!="letter";})
    
    data.forEach(function(d){
        d.groups=groupNames.map(function(name){return {name:name,value:+d[name]};})
    });
    
    x0.domain(data.map(function(d){return d.letter;}));
    x1.domain(groupNames).rangeRoundBands([0, x0.rangeBand()]);
    
    y.domain([0,d3.max(data,function(d){
        return d3.max(d.groups,function(d){
            return d.value;
        });
    })]);
    
    svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
  .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Letter Fun");

    var state = svg.selectAll(".state")
    .data(data)
  .enter().append("g")
    .attr("class", "g")
    .attr("transform", function(d) { return "translate(" + x0(d.letter) + ",0)"; });
    
    state.selectAll("rect")
    .data(function(d) { return d.groups; })
  .enter().append("rect")
     .attr("width", x1.rangeBand())
     .attr("x", function(d) { return x1(d.name); })
     .attr("y", function(d) { return y(d.value); })
     .attr("height", function(d) { return height - y(d.value); })
     .style("fill", function(d) { return color(d.name); });
    
    

如果您对代码有任何了解,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多