标题和坐标轴标签

4

我已成功创建了X和Y轴的标签,并成功为图表添加了标题。但是,问题在于如果我修改了图表的边缘,标签位置就会混乱。

以下是我更改图表边缘的代码片段:

    var margin = {top: 60, right: 60, bottom: 60, left:120}  

创建标签的代码片段:

    //Create Title 
    svg.append("text")
    .attr("x", w / 2 )
    .attr("y", 0)
    .style("text-anchor", "middle")
    .text("Title of Diagram");

    //Create X axis label   
    svg.append("text")
    .attr("x", w / 2 )
    .attr("y",  h + margin.bottom)
    .style("text-anchor", "middle")
    .text("State");

    //Create Y axis label
    svg.append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 0-margin.left)
    .attr("x",0 - (h / 2))
    .attr("dy", "1em")
    .style("text-anchor", "middle")
    .text("Revenue");  

JsFiddle:
http://jsfiddle.net/u63T9/

这里有另一种我可以接受的替代方法:
我基本上利用比例尺找到基础坐标。然后再加减少许多,直到我对位置感到满意。这种方法实际上可以跟踪边距的变化。

    //Create title 
    svg.append("text")
    .attr("x", w / 2 )
    .attr("y",  yScale(d3.max(input, function(d) { return d.CustomerCount; })) - 20 )
    .style("text-anchor", "middle")
    .text("Title of Graph");

    //Create X axis label   
    svg.append("text")
    .attr("x", w / 2 )
    .attr("y",  yScale(0) + 40 )
    .style("text-anchor", "middle")
    .text("State");

    //Create Y axis label
    svg.append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", xScale(0) - 80 )
    .attr("x",0 - (h / 2))
    .attr("dy", "1em")
    .style("text-anchor", "middle")
    .text("Revenue"); 

除了计算标签所需的空间并确保边距至少那么大之外,您实际上无法做任何事情。 - Lars Kotthoff
这里提供解决方案:http://www.d3noob.org/2012/12/adding-axis-labels-to-d3js-graph.html。您可以在此免费下载完整的PDF《D3技巧和技巧》:https://leanpub.com/D3-Tips-and-Tricks。 - hexicle
1个回答

12

我使用一个简单的函数来测量文本,然后根据其计算边距。

// create a dummy element, apply the appropriate classes,
// and then measure the element
function measure(text, classname) {
  if(!text || text.length === 0) return {height: 0, width: 0};

  var container = d3.select('body').append('svg').attr('class', classname);
  container.append('text').attr({x: -1000, y: -1000}).text(text);

  var bbox = container.node().getBBox();
  container.remove();

  return {height: bbox.height, width: bbox.width};
}

现在您可以使用

var titleSize = measure('my title', 'chart title'),
    margin.top = titleSize.height + 20; // add whatever padding you want 

我在http://jsfiddle.net/uzddx/2/上更新了你的示例。当您修改标题的字体大小时,可以看到顶部间距会重新调整大小。您可以为左边距做类似的事情,这样您的标签就不会离y轴太远了。


谢谢Bill,但我对D3还很陌生,无法完全理解你的解决方案。 - DataByDavid
这与D3无关,我只是在SVG中使用getBBox来测量文本。一旦你有了文本字符串的高度,你可以修改边距使它们正确地适配。换句话说,不要硬编码你的边距,测量标签并根据它们的大小设置你的边距。 - Bill
我已经尝试使用d3,并发现在安装jsdom时出现问题,然后按照http://www.steveworkman.com/node-js/2012/installing-jsdom-on-windows/进行操作,但仍然没有成功。相反,有https://github.com/cheeriojs/cheerio。它是jsdom的替代品。所以有没有办法使用cherrio,d3,d3-measure-text一起工作。我的最终目标是实现在c#中获取图形.Measurestring中获得的文本尺寸。请注意,npm-canvas不是一个选项,因为它需要chiro并且难以安装在Windows上。请救救我。我已经花了很多时间了。 - choudhury smrutiranjan parida

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接