简体   繁体   English

d3.js 条形图 - 无 Y 轴刻度

[英]d3.js Bar Chart - No Y Axis scale

I have a d3.js bar chart, but the X axis columns have no height, presumably because there is no data/scale for the Y axis.我有一个 d3.js 条形图,但 X 轴列没有高度,大概是因为 Y 轴没有数据/比例。 The last column should display.最后一列应显示。

在此处输入图像描述

The JSON: JSON:

[{"Domain":"Knowledge","Knowledge":0},{"Domain":"Problem Solving","problem_solving":0},{"Domain":"Skill","skill":0},{"Domain":"Transferable","transferable":100}]

The chart:图表:

var margin = {top: 50, right: 135, bottom: 70, left: 80},
    width = 1050 - margin.left - margin.right,
    height = 540 - margin.top - margin.bottom;  

  var svg = d3.select("#domains")
    .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 + ")");

// load the data
d3.json("json/domains.json", function(error, data) {



// Transpose the data into layers
var dataset = d3.layout.stack()(["Knowledge", "Problem Solving, Skill, Transferable"].map(function(lvl) {
  return data.map(function(d) {
    return {
      x: d.Domain,
      y: d[lvl]
    };
  });
}));

  var disciplines = d3.nest()
    .key(function(d){return d.Domain})
    .rollup(function(leaves){
      return d3.sum(leaves, function(d) {return d3.sum(d3.values(d))});
    })
    .entries(data);

  // Set x, y and colors
  var x = d3.scale.ordinal()
    .domain(dataset[0].map(function(d) { return d.x; }))
    .rangeRoundBands([10, width-10], 0.35, 0);

  var y = d3.scale.linear()
    .domain([0, d3.max(dataset, function(d) {  return d3.max(d, function(d) { return d.y0 + d.y; });  })])
    .range([height, 0]);

  var colors = ["#83d1c4", "#f17950", "#838BD1", "#F150BE"];

  // Define and draw axes
  var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(5)
    .tickSize(-width, 0, 0)
      .tickFormat(function(d) {
    return d;     
  });

  var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .outerTickSize(0)
  
  
  d3.select('.y axis .tick:first-child').remove();
  
  var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-0, 0])
  .html(function(d) {
    return d.y + '%';
  })
    
svg.call(tip);

  svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(0,0)")
    .call(yAxis);


  svg.append("g")
    .call(xAxis)
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
    
    svg.append("text")
  .attr("x", 390 )
  .attr("y",  480 )
  .style("text-anchor", "middle")
  .text("Disciplines");
    
svg.append("text")
   .attr("x", -200 )
   .attr("y",  -40 )
   .attr("transform", "rotate(-90)" )
   .attr('style', 'font-size:12px')
   .style("text-anchor", "middle")
   .text("Percentage of Learning Events");

  // Create groups for each series, rects for each segment
  var groups = svg.selectAll("g.group")
    .data(dataset)
    .enter().append("g")
    .attr("class", "group")
    .style("fill", function(d, i) { return colors[i]; });

//  var svg = d3.select("svg");
  var bar = groups.selectAll("g")
    .data(function(d) { return d; })
    .enter().append("g")
    .attr("transform", function(d, i) {
      return "translate(" + x(d.x) + ", 0)";
    });

  var sum=0;
  bar.append("rect")
    .attr("y", function(d) { return y(d.y0 + d.y); })
    .attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
    .attr('class', 'segment')
    .attr("width", x.rangeBand())
    .on('mouseover', tip.show)
    .on('mouseout', tip.hide);


  columns = svg.append("g")
    .selectAll("text").data(disciplines)
    .enter().append("text")
    .attr("x", function(d){
      return x(d.key) + x.rangeBand()/2
    })
    .attr("y", function (d) {
      return y(d.values);
    })
    .attr("dy", "-0.7em")
    .attr('style', 'font-size:11px')
    .text( function (d){
      return d3.format(".2f")(d.values) + '%';
    })
    .style({fill: 'black', "text-anchor": "middle"});



  // Draw legend
var legend = svg.selectAll(".legend")
  .data(colors)
  .enter().append("g")
  .attr("class", "legend")
    .attr('style', 'font-size:12px')
  .attr("transform", function(d, i) {
    return "translate(30," + i * 19 + ")";
  });

  legend.append("rect")
    .attr("x", width - 18)
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", function(d, i) {return colors.slice().reverse()[i];});

  legend.append("text")
    .attr("x", width + 5)
    .attr("y", 9)
    .attr("dy", ".35em")
    .style("text-anchor", "start")
    .text(function(d, i) {
      switch (i) {
      case 0:
        return "Knowledge";
      case 1:
        return "Problem Solving";
      case 2:
        return "Skill";
      case 3:
        return "Transferable";
      }
    });
    
    });

I have another d3.js chart, which uses practically the same chart code as above and JSON format, just the data is different, columns and Y axis graduations show OK:我还有另一个d3.js图表,它使用与上面几乎相同的图表代码和JSON格式,只是数据不同,列和Y轴刻度显示OK:

在此处输入图像描述

UPDATE更新

Changed 'Domain' key in the JSON to 'Dom' so as not to cause any conflict with the d3.js function .domain (makes no difference to the chart though...):将 JSON 中的 'Domain' 键更改为 'Dom',以免与 d3.js function .domain造成任何冲突:

JSON: JSON:

[{"Dom":"Knowledge","Knowledge":0},{"Dom":"Problem Solving","problem_solving":0},{"Dom":"Skill","skill":0},{"Dom":"Transferable","transferable":100}]

Chart:图表:

var margin = {top: 50, right: 135, bottom: 70, left: 80},
    width = 1050 - margin.left - margin.right,
    height = 540 - margin.top - margin.bottom;  

  var svg = d3.select("#domains")
    .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 + ")");

// load the data
d3.json("json/domains.json", function(error, data) {



// Transpose the data into layers
var dataset = d3.layout.stack()(["Knowledge", "Problem Solving", "Skill", "Transferable"].map(function(lvl) {
  return data.map(function(d) {
    return {
      x: d.Dom,
      y: d[lvl]
    };
  });
}));

  var domains = d3.nest()
    .key(function(d){return d.Dom})
    .rollup(function(leaves){
      return d3.sum(leaves, function(d) {return d3.sum(d3.values(d))});
    })
    .entries(data);

  // Set x, y and colors
  var x = d3.scale.ordinal()
    .domain(dataset[0].map(function(d) { return d.x; }))
    .rangeRoundBands([10, width-10], 0.35, 0);

  var y = d3.scale.linear()
    .domain([0, d3.max(dataset, function(d) {  return d3.max(d, function(d) { return d.y0 + d.y; });  })])
    .range([height, 0]);

  var colors = ["#50E0C8", "#f17950", "#C283D1", "#50BCF1"];

  // Define and draw axes
  var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(5)
    .tickSize(-width, 0, 0)
      .tickFormat(function(d) {
    return d;     
  });

  var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .outerTickSize(0)
  
  
  d3.select('.y axis .tick:first-child').remove();
  
  var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-0, 0])
  .html(function(d) {
    return d.y + '%';
  })
    
svg.call(tip);

  svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(0,0)")
    .call(yAxis);


  svg.append("g")
    .call(xAxis)
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
    
    svg.append("text")
  .attr("x", 390 )
  .attr("y",  480 )
  .style("text-anchor", "middle")
  .text("Domains");
    
svg.append("text")
   .attr("x", -200 )
   .attr("y",  -40 )
   .attr("transform", "rotate(-90)" )
   .style("text-anchor", "middle")
   .text("Percentage of Learning Events");

  // Create groups for each series, rects for each segment
  var groups = svg.selectAll("g.group")
    .data(dataset)
    .enter().append("g")
    .attr("class", "group")
    .style("fill", function(d, i) { return colors[i]; });

//  var svg = d3.select("svg");
  var bar = groups.selectAll("g")
    .data(function(d) { return d; })
    .enter().append("g")
    .attr("transform", function(d, i) {
      return "translate(" + x(d.x) + ", 0)";
    });

  var sum=0;
  bar.append("rect")
    .attr("y", function(d) { return y(d.y0 + d.y); })
    .attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
    .attr('class', 'segment')
    .attr("width", x.rangeBand())
    .on('mouseover', tip.show)
    .on('mouseout', tip.hide);


  columns = svg.append("g")
    .selectAll("text").data(domains)
    .enter().append("text")
    .attr("x", function(d){
      return x(d.key) + x.rangeBand()/2
    })
    .attr("y", function (d) {
      return y(d.values);
    })
    .attr("dy", "-0.7em")
    .attr('style', 'font-size:11px')
    .text( function (d){
      return d3.format(".2f")(d.values) + '%';
    })
    .style({fill: 'black', "text-anchor": "middle"});


    
    });

Fixed some errors and simplified your code.修复了一些错误并简化了您的代码。 See it working in the fiddle:看到它在小提琴中工作:

 var margin = {top: 50, right: 135, bottom: 70, left: 80}, width = 1050 - margin.left - margin.right, height = 540 - margin.top - margin.bottom; var svg = d3.select("#domains").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 + ")"); // load the data const data = [{"Domain":"Knowledge","knowledge":0},{"Domain":"Problem Solving","problem_solving":0},{"Domain":"Skill","skill":0},{"Domain":"Transferable","transferable":100}]; const normalized = data.map(item => { const name = item['Domain']; const attr = name.toLowerCase().replace(' ', '_'); const value = item[attr]; return {name, value}; }); console.log('N: ', normalized); /* // Transpose the data into layers var dataset = d3.layout.stack()(["Knowledge", "Problem Solving, Skill, Transferable"].map(function(lvl) { return data.map(function(d) { return { x: d.Domain, y: d[lvl] }; }); })); var disciplines = d3.nest().key(function(d){return d.Domain}).rollup(function(leaves){ return d3.sum(leaves, function(d) {return d3.sum(d3.values(d))}); }).entries(data); */ // Set x, y and colors var x = d3.scale.ordinal().domain(normalized.map(item => item.name)).rangeRoundBands([10, width-10], 0.35, 0); const maxValue = normalized.reduce((max, item) => Math.max(max, item.value), 0); var y = d3.scale.linear().domain([0, maxValue]).range([height, 0]); var colors = ["#83d1c4", "#f17950", "#838BD1", "#F150BE"]; // Define and draw axes var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5).tickSize(-width, 0, 0).tickFormat(function(d) { return d; }); var xAxis = d3.svg.axis().scale(x).orient("bottom").outerTickSize(0) d3.select('.y axis.tick:first-child').remove(); /* var tip = d3.tip().attr('class', 'd3-tip').offset([-0, 0]).html(function(d) { return dy + '%'; }) svg.call(tip); */ svg.append("g").attr("class", "y axis").attr("transform", "translate(0,0)").call(yAxis); svg.append("g").call(xAxis).attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis); svg.append("text").attr("x", 390 ).attr("y", 480 ).style("text-anchor", "middle").text("Disciplines"); svg.append("text").attr("x", -200 ).attr("y", -40 ).attr("transform", "rotate(-90)" ).attr('style', 'font-size:12px').style("text-anchor", "middle").text("Percentage of Learning Events"); // Create groups for each series, rects for each segment var groups = svg.selectAll("g.group").data(normalized).enter().append("g").attr("class", "group").style("fill", function(d, i) { return colors[i]; }); groups.append("rect").attr("y", function(d) { return y(d.value); }).attr("x", d => x(d.name)).attr("height", function(d) { return y(0) - y(d.value); }).attr('class', 'segment').attr("width", x.rangeBand()) //.on('mouseover', tip.show) //.on('mouseout', tip.hide); columns = svg.append("g").selectAll("text").data(normalized).enter().append("text").attr("x", function(d){ return x(d.name) + x.rangeBand()/2 }).attr("y", function (d) { return y(d.value); }).attr("dy", "-0.7em").attr('style', 'font-size:11px').text( function (d){ return d3.format(".2f")(d.value) + '%'; }).style({fill: 'black', "text-anchor": "middle"}); // Draw legend var legend = svg.selectAll(".legend").data(colors).enter().append("g").attr("class", "legend").attr('style', 'font-size:12px').attr("transform", function(d, i) { return "translate(30," + i * 19 + ")"; }); legend.append("rect").attr("x", width - 18).attr("width", 18).attr("height", 18).style("fill", function(d, i) {return colors.slice().reverse()[i];}); legend.append("text").attr("x", width + 5).attr("y", 9).attr("dy", ".35em").style("text-anchor", "start").text(function(d, i) { switch (i) { case 0: return "Knowledge"; case 1: return "Problem Solving"; case 2: return "Skill"; case 3: return "Transferable"; } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script> <div id="domains" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM