在条形图中向<rect>的两端添加标签

时间:2016-03-29 16:47:39

标签: javascript d3.js

我使用D3将一些数据显示为水平条形图。在8个不同的比例上,值通常在-10到+10之间。我有条形渲染,但我无法弄清楚如何为每个轴的extreems添加标签。

到目前为止,我有:

bars with no lables

但我想实现类似的目标:

enter image description here

换句话说,每个刻度的每个极端都有一个标签。 我发现了许多将数据标签添加到条形图中的示例(例如值),但我想知道如何强制在容器的极端处呈现字符串数组。

目前,我正在从数组渲染数据,并且我将标签存储在其他2个数组中,例如。

var data = [10, 5, -5, -10, 2, -2, 8, -8];
var leftLabels = ["label 1","label 2", ...];
var rightLabels = ["label 1", "label 2", ...];

欢迎任何想法或链接到示例。

2 个答案:

答案 0 :(得分:2)

我不是d3.js的专家,但我认为这很容易做到。有不同的方法可以解决它。我为您的用例创建了pen

我将粘贴以下代码的重要部分。在您的图表中,您必须进行一些调整以满足您的需求。随意玩这些值,直到您感觉它们稳定为止。

// Your array containing labels for left and right values

var leftSideData = ["left1", "left2", "left3", "left4", "left5", "left6", "left7", "left8"];

var rightSideData = ["right1", "right2", "right3", "right4", "right5", "right6", "right7", "right8"];

var left = svg.selectAll(".leftData")
    .data(leftSideData)
    .enter().append("g")
    .attr("class", "leftVal")
    .attr("transform", function(d, i) {
      return "translate(0," + i * 57 + ")";
    });

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

  var right = svg.selectAll(".rightData")
    .data(rightSideData)
    .enter().append("g")
    .attr("class", "rightVal")
    .attr("transform", function(d, i) {
      return "translate(0," + i * 57 + ")";
    });

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

我不会说这是完美的,但我希望你能了解如何处理它。一切顺利!!

答案 1 :(得分:0)

这很有趣,只是通过询问SE上的q我发现它有助于我重新解决问题..然后一段时间之后,新尝试产生结果。其他人都找到了吗?

我设法通过改变创建SVG的方式使其工作。所以我现在有以下结构:

<SVG>
><g> (one for each bar)
>><text>
>><rect>
>><text>
><other stuff like axies>

事实证明,<text>元素无法添加到<rect>个元素(他们可以添加它们,但它们不会渲染)。

代码是:

var data = [10,2,4,-10,...etc...];

var leftLabels = ["left 1","left 1", ...etc...];

var rightLabels = ["right 1","right 2", ...etc...];

//chart dimentions
var margin = { top: 20, right: 30, bottom: 40, left: 30 },
    width = 600 - margin.left - margin.right,
    barHeight = 30,
    height = barHeight * data.length;

//chart bar scaling
var x = d3.scale.linear()
.range([100, width-100]);

var y = d3.scale.ordinal()
.rangeRoundBands([0, height], 0.1);

var chart = d3.select(".chartsvg")
.attr("width", width + margin.left + margin.right)
.attr("height", barHeight * data.length + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

x.domain([d3.min(data), d3.max(data)]);

//append a g for each data item 
var bar = chart.selectAll(".bar")
  .data(data)
  .enter()
  .append("g");

//in each bar add a rect for the bar chart bar
bar.append("rect")
  .attr("class", function (d) { return "bar--" + (d < 0 ? "negative" : "positive"); })
  .attr("x", function (d) { return x(Math.min(0, d)); })
  .attr("y", function (d, i) { return i* barHeight; })
  .attr("width", function (d) { return Math.abs(x(d) - x(0)); })
  .attr("height", barHeight-1);

//append the labels to each g using the label data
bar.append("text")
    .data(rightLabels)
    .attr("x", width)
    .attr("y", function (d, i) { return (i * barHeight)+barHeight/2; })
    .attr("dy", ".5em")
    .attr("fill","steelblue")
    .attr("text-anchor","end")
    .text(function (d) { return d; });

bar.append("text")
    .data(leftLabels)
    .attr("x", 0)
    .attr("y", function (d, i) { return (i * barHeight) + barHeight / 2; })
    .attr("dy", ".5em")
    .attr("fill","darkorange")
    .attr("text-anchor", "start")
    .text(function (d) { return d; });
//then append axis etc...

格式化:需要注意的其他事项。事实证明,要为标签中的文本着色,您需要使用“笔划”和“填充”属性。这些大致等同于文本上的HTML“颜色”属性。