【问题标题】:D3.js Auto font-sizing based on nodes individual radius/diameterD3.js 基于节点单个半径/直径的自动字体大小
【发布时间】:2013-12-05 13:49:27
【问题描述】:

如何让 D3.js 根据每个节点的半径/直径自动调整每个节点的字体大小?

我使用了一种允许自动增加insize的样式

  node.append("text")
      .attr("dy", ".3em")
      .style("text-anchor", "middle")
      .text(function(d) { return d.className.substring(0, d.r / 3); })
      .style("font-size", "10px") // initial guess
//This is what gives it increased size...
      .style("font-size", function(d) { return (2 * d.r - 10) / this.getComputedTextLength() * 10 + "px"; })

; * 10 + "像素"; })

此效果会从较小的节点中删除文本。我还有一个缩放功能,我可以增加一个原本覆盖 12 px 的点来覆盖我的整个屏幕。

.call(d3.behavior.zoom().scaleExtent([1, 200]).on("zoom", zoom))

有没有一种方法可以单独自动格式化 node-font; 以适当的大小写入,因此当放大时,调用的 node-font 将显示为与 node-size 与单个字体成比例-尺寸适合所有人?

正确列出圆圈:NAME(SIZE)
我希望有一个可以学习的工作示例。因此,在图像尺寸下,在 P 旁边的驱动圈以北的小绿点将有黑色的无法阅读的文字,直到我们放大查看圆圈上写的内容。目标是在放大时具有成比例的可读字体..?

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    您可以通过根据容器大小动态设置文本大小来做到这一点。为此,您必须添加文本、获取其边界框、获取容器元素的边界框并根据当前字体大小和这些边界框得出正确的字体大小。

    代码看起来像这样。

    // ...
      .append("text")
      .text("text")
      .style("font-size", "1px")
      .each(getSize)
      .style("font-size", function(d) { return d.scale + "px"; });
    
    function getSize(d) {
      var bbox = this.getBBox(),
          cbbox = this.parentNode.getBBox(),
          scale = Math.min(cbbox.width/bbox.width, cbbox.height/bbox.height);
      d.scale = scale;
    }
    

    【讨论】:

    • 效果很好...是否有一个简单的修复方法可以在单词前后留出空间或将单词大小缩小几个步骤?
    • 这完全取决于cscale 的确定方式——您可以在此处添加一个因子或为bbox.width 添加一个常量偏移量以获得空格。
    【解决方案2】:

    为了在一个圆圈内偏移文本,而不是沿着直径运行,我以不同的方式实现:

    dy 在圆内向上或向下移动文本节点,用于计算宽度或弦以调整文本大小。

    然后将比例存储在文本元素的数据属性中,而不是修改源数据。

    jsfiddle

    function appendScaledText(parentGroup, textVal, dyShift) {
      parentGroup
        .append("text")
        .attr("dy", dyShift)
        .attr("text-anchor", "middle")
        .attr("dominant-baseline", "central")
        .attr("font-family", "sans-serif")
        .attr("fill", "white")
        .text(textVal)
        .style("font-size", "1px")
        .each(getSize)
        .style("font-size", function() {
          return d3.select(this).attr("data-scale") + "px";
        });
    }
    
    function getSize() {
      var d3text = d3.select(this);
    
      // in other cases could be parentElement or nextElementSibling
      var circ = d3.select(this.previousElementSibling); 
      var radius = Number(circ.attr("r"));
      var offset = Number(d3text.attr("dy"));
    
      // TODO: this could be bounding box instead
      var textWidth = this.getComputedTextLength();
    
      // TODO: could adjust based on ratio of dy to radius 
      var availWidth = chordWidth(Math.abs(offset), radius); 
    
      // fixed 15% 'padding', could be more dynamic/precise based on above TODOs
      availWidth = availWidth * 0.85;
    
      d3text.attr("data-scale", availWidth / textWidth); 
    }
    
    function chordWidth(dFromCenter, radius) {
      if (dFromCenter > radius) return Number.NaN;
      if (dFromCenter === radius) return 0;
      if (dFromCenter === 0) return radius * 2;
    
      // a^2 + b^2 = c^2
      var a = dFromCenter;
      var c = radius;
      var b = Math.sqrt(Math.pow(c, 2) - Math.pow(a, 2)); // 1/2 of chord length
    
      return b * 2;
    }
    

    【讨论】:

      【解决方案3】:

      或者,您可以创建嵌入每个节点的文本标签,如下所示:

      this.g.append("g")
        .attr("class", "labels")
        .selectAll(".mytext")
        .data(NODE_DATA)
        .enter()
        .append("text")
        .text(function (d) {
           return d.LabelText; // Here label text is the text that you want to show in the node
        })
        .style("font-size", "1px")
        .attr("dy", ".35em") // You can adjust it
        .each(function (d) {
            var r = Number(d.Size), a = this.getComputedTextLength(),
                c=0.35, // Same as dy attribute value
                b = 2*Math.sqrt(r*r-c*c), s = Math.min(r, b/a);
            d.fs = s;
        })
        .style("font-size", function (d) {
           return d.fs + "px";
        })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-03
        • 1970-01-01
        • 1970-01-01
        • 2017-10-09
        • 1970-01-01
        • 1970-01-01
        • 2017-03-11
        相关资源
        最近更新 更多