【问题标题】:Labels on Stack bars and line in D3.js chartD3.js 图表中堆栈栏和线条上的标签
【发布时间】:2019-04-18 10:46:15
【问题描述】:

我正在 D3.js 中设计带有双轴折线图的堆叠条形图,但无法在其上对齐标签。

以下是我尝试过的代码- https://plnkr.co/edit/doobXBC5hgzvGwDLvArF?p=preview

我需要将标签垂直放置在每个堆栈的中间,并且还需要每个刻度线上方的标签。有人可以帮忙吗,因为我对 D3.js 很陌生,对我可以在这里使用的函数/样式技术了解不多。

Javascript 代码如下 -

var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 660 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
.rangeRoundBands([0, width-150], .1);

y = d3.scale.linear()
.rangeRound([height, 0]).domain([0,100]);

y1 = d3.scale.linear().range([height, 0]).domain([0,1000]);//marks can have min 0 and max 100

var yAxisRight = d3.svg.axis().scale(y1)
    .orient("right").ticks(10);

var color = d3.scale.ordinal()
    .range(["#ADD8E6", "#FF7F50", "lightgreen"  ]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickFormat(d3.format(".2s"));

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 + ")");

d3.csv("class.csv", function(error, data) {
  if (error) throw error;
  //filter out name and average
  color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Name" && key !=="Average"; }));
  data.forEach(function(d) {
    var y0 = 0;
    d.group = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
    d.total = d.group[d.group.length - 1].y1;
  });


  x.domain(data.map(function(d) { return d.Name; }));
  //stores toltal headcount
  y.domain([0, d3.max(data, function(d) { return d.total; })]);

  //line function for averageLine
  var averageline = d3.svg.line()
      .x(function(d) { return x(d.Name) + x.rangeBand()/2; })
      .y(function(d) { return y1(d.Average); });

  //this will make the y axis to teh right
  svg.append("g")               
        .attr("class", "y axis")    
        .attr("transform", "translate(" + (width-100) + " ,0)") 
        .style("fill", "red")       
        .call(yAxisRight);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  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("Bookings");


var state = svg.selectAll(".state")
      .data(data)
    .enter().append("g")
      .attr("class", "g")
      .attr("transform", function(d) { return "translate(" + x(d.Name) + ",0)"; });

var ages_enter = state.selectAll("rect")
      .data(function(d) { return d.group; })
    .enter();
  ages_enter.append("rect")
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.y1); })
      .attr("height", function(d) { return y(d.y0) - y(d.y1); })
      .style("fill", function(d) { return color(d.name); });
  ages_enter.append("text")
      .text(function(d) { return d3.format(".2s")(d.y1-d.y0 ); })
      .attr("y", function(d) { return y(d.y1); })
      //.attr("text-anchor", "right")
      .style("stroke", 'black')
      .style("font-family", "calibri")
      .style("font-size", "12px")
      .style("text-anchor",'left')
      .attr("dominant-baseline", "middle");
      //.attr("y", function(d) { return y(d.frequency/2); })
      //.attr("y", height)
      //.attr("y", function(d) { return y(d.frequency); })
      //.attr("y", function(d) { return y(d.frequency); })
      //.attr("y", function(d) { return Math.min(y(d.frequency) + 10, height); });


  svg.append("path")        // Add the valueline path.
        .attr("d", averageline(data));  
  //add teh legend
  var legend = svg.selectAll(".legend")
      .data(color.domain().slice().reverse())
    .enter().append("g")
      .attr("class", "legend")
      .attr("transform", function(d, i) { return "translate(0," + i * 30 + ")"; });

  legend.append("rect")
      .attr("x", width - 18)
      .attr("width", 18)
      .attr("height", 18)
      .style("fill", color);

  legend.append("text")
      .attr("x", width - 24)
      .attr("y", 9)
      .attr("dy", ".35em")
      .style("text-anchor", "end")
      .text(function(d) { return d; });

});

【问题讨论】:

    标签: javascript html css d3.js


    【解决方案1】:

    能否请将以下两行添加到ages_enter.append("text")

    .attr("x", function(d) { return -y(d.y1)-20; }) .attr("变换","旋转(-90)")

    所以你的代码看起来像这样;

    ages_enter.append("text")
          .text(function(d) { return d3.format(".2s")(d.y1-d.y0 ); })
          .attr("x", function(d) { return -y(d.y1)-20; })
          .attr("transform","rotate(-90)")
          //.attr("text-anchor", "right")
          .style("stroke", 'black')
          .style("font-family", "calibri")
          .style("font-size", "12px")
          .style("text-anchor",'left')
          .attr("dominant-baseline", "middle");
    

    【讨论】:

    • 它没有解决我的目的。请在上述更改后见下文。 plnkr.co/edit/doobXBC5hgzvGwDLvArF?p=preview这里还有如何给折线图添加标签。
    • 按照我之前对ages_enter.append("text")的评论中提到的更改后,您能否将代码粘贴到评论部分中?
    • ages_enter.append("text") .text(function(d) { return d3.format(".2s")(d.y1-d.y0 ); }) .attr(" x", function(d) { return -y(d.y1)-20; }) .attr("transform","rotate(-90)") //.attr("text-anchor", "right" ) .style("stroke", 'black') .style("font-family", "calibri") .style("font-size", "10px") .style("text-anchor",'middle' ) .attr("主要基线", "中间");
    • 请用这个sn-p替换---->>>ages_enter.append("text") .text(function(d) { return d3.format(".2s")( d.y1-d.y0 ); }) .attr("x", function(d) { return -y(d.y1)-20; }) .attr("transform","rotate(-90)" ) .attr("y", function(d) { return 20; }) .attr("transform","rotate(-90)")
    • 感谢它现在的工作。能否请您告诉我如何在此处向折线图添加标签。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 2017-08-27
    • 1970-01-01
    • 2014-01-20
    • 2019-01-05
    • 2019-08-27
    相关资源
    最近更新 更多