在D3.Js中的rect中剪切文本 [英] Cut the text in a rect in D3.Js

查看:92
本文介绍了在D3.Js中的rect中剪切文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个树状组织,并且在这棵树上,我有一些rect,具有|字符.这意味着必须将在|之后编写的文本放在rect的末尾.

I have a tree organization and on this tree, I have some rect, who have a | character. It means that the text that is written after this | must be placed at the end of the rect.

下面是代码(将其复制以查看结果):

Here is the code (copy it for see the result):

<!DOCTYPE html>
<head>

    <meta charset="utf-8"> 
    <title>Graphique DPGF</title>
    <style>

.node rect {
  cursor: pointer;
  fill: #fff;
  fill-opacity: 0.5;
  stroke: #3182bd;
  stroke-width: 1.5px;
}

div#div svg {
    float: left;
}

.node text {
  font: 10px sans-serif;
  pointer-events: none;
}

.link {
  fill: none;
  stroke: #9ecae1;
  stroke-width: 1.5px;
}

    </style>
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>


var margin = {top: 30, right: 20, bottom: 30, left: 20},
    width = 400,
    barHeight = 20,
    barWidth = (width - margin.left - margin.right) * 0.8;

var i = 0,
    duration = 0,
    root;


var path = [];   
path[0] = "D.json";
path[1] = "D.json";
path[2] = "D.json";
create_a_tree_obj(path);


function create_a_tree_obj(path) {
    var i = 0;
    var div;
    var svg_array = [];

    if (i === 0) {
        div = d3.select("body").append("div")
            .attr("id", "div");
    }
    for (i ; path[i]; i++) {
        svg_array[i] = div.append("div").append("svg")
        .attr("id", "" + i)
        .attr("width", 600) // + margin.left + margin.right)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        add_the_tree_graph(svg_array, path, i);
    }
}


function add_the_tree_graph(svg_array, path, i) {
    var root;

    d3.json(path[i], function(error, json) {
        if (error) throw error;
        for (; path[i]; i++) { 
            root = d3.hierarchy(json);
            root.x0 = 0;
            root.y0 = 0;
            update(root, svg_array[i], "" + i);
        }
    });
}    


function update(source, svg_var, svg_id) {

  // Compute the flattened node list.
    var nodes = source.descendants();
    var height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom);

    document.getElementById(svg_id).setAttribute("height", height);

  d3.select(self.frameElement).transition()
      .duration(duration)
      .style("height", height + "px");

  // Compute the "layout". TODO https://github.com/d3/d3-hierarchy/issues/67
  var index = -1;
  source.eachBefore(function(n) {
    n.x = ++index * barHeight;
    n.y = n.depth * 20;
  });

  // Update the nodes…
  var node = svg_var.selectAll(".node")
    .data(nodes, function(d) { return d.id || (d.id = ++i); });

  var nodeEnter = node.enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
      .style("opacity", 0);

  // Enter any new nodes at the parent's previous position.
  nodeEnter.append("rect")
      .attr("y", -barHeight / 2)
      .attr("height", barHeight)
      .attr("width", barWidth)
      .style("fill", color)
      .on("click", function(d) {
      if (d.children) {
        d._children = d.children;
        d.children = null;
      } else {
        d.children = d._children;
        d._children = null;
      }
      update(source, svg_var, svg_id);
    });

  nodeEnter.append("text")
      .attr("dy", 3.5)
      .attr("dx", 5.5)
      .text(function(d) { return d.data.attributes; });

  // Transition nodes to their new position.
    nodeEnter.transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
      .style("opacity", 1);
    node.transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
      .style("opacity", 1)
    .select("rect")
      .style("fill", color);

  // Transition exiting nodes to the parent's new position.
  node.exit().transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
      .style("opacity", 0)
      .remove();
}


function color(d) {
  return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}

</script>

这里是D.Json文件:

And here the D.Json file :

{"attributes": "DPGF", "children": [{"attributes": "LOT:  nom 13.CVC", "children": [{"attributes": "Tous_DPGF:  Profondeur 1", "children": [{"attributes": "Poste:  Rang Rang 1 | Total = 20", "children": [{"attributes":"Debut_poste_Excel 0.0"}, {"attributes":"Fin_poste_Excel 19.0"}, {"attributes":"Mot_cle debut"}, {"attributes":"Rang Rang 1"}]}, {"attributes": "Poste:  Rang Rang 1 | Total = 41", "children": [{"attributes":"Debut_poste_Excel 20.0"}, {"attributes":"Fin_poste_Excel 20.0"}, {"attributes":"Mot_cle chauffage"}, {"attributes":"Rang Rang 1"}]}, {"attributes": "Poste:  Rang Rang 1 | Total = 45", "children": [{"attributes":"Debut_poste_Excel 21.0"}, {"attributes":"Fin_poste_Excel 23.0"}, {"attributes":"Mot_cle Préambule"}, {"attributes":"Rang Rang 1"}]}, {"attributes": "Poste:  Rang Rang 1 | Total = 50", "children": [{"attributes":"Debut_poste_Excel 24.0"}, {"attributes":"Fin_poste_Excel 25.0"}, {"attributes":"Mot_cle Préambule"}, {"attributes":"Rang Rang 1"}]}, {"attributes": "Poste:  Rang Rang 1 | Total = 54", "children": [{"attributes":"Debut_poste_Excel 26.0"}, {"attributes":"Fin_poste_Excel 27.0"}, {"attributes":"Mot_cle production thermique"}, {"attributes":"Rang Rang 1"}]}, {"attributes": "Poste:  Rang Rang 1 | Total = 94", "children": [{"attributes":"Debut_poste_Excel 28.0"}, {"attributes":"Fin_poste_Excel 65.0"}, {"attributes":"Mot_cle chauffage"}, {"attributes":"Rang Rang 1"}, {"attributes": "Tous_DPGF:  Profondeur 2", "children": [{"attributes": "Poste:  Rang Rang 2", "children": [{"attributes":"Debut_poste_Excel 31.0"}, {"attributes":"Fin_poste_Excel 65.0"}, {"attributes":"Mot_cle Échangeur"}, {"attributes":"Rang Rang 2"}, {"attributes": "Tous_DPGF:  Profondeur 3", "children": [{"attributes": "Poste:  Rang Rang 4", "children": [{"attributes":"Debut_poste_Excel 35.0"}, {"attributes":"Fin_poste_Excel 35.0"}, {"attributes":"Mot_cle Manchon"}, {"attributes":"Rang Rang 4"}]}, {"attributes": "Poste:  Rang Rang 4", "children": [{"attributes":"Debut_poste_Excel 36.0"}, {"attributes":"Fin_poste_Excel 36.0"}, {"attributes":"Mot_cle Vanne"}, {"attributes":"Rang Rang 4"}]}, {"attributes": "Poste:  Rang Rang 4", "children": [{"attributes":"Debut_poste_Excel 37.0"}, {"attributes":"Fin_poste_Excel 37.0"}, {"attributes":"Mot_cle Thermomètre"}, {"attributes":"Rang Rang 4"}]}, {"attributes": "Poste:  Rang Rang 4", "children": [{"attributes":"Debut_poste_Excel 38.0"}, {"attributes":"Fin_poste_Excel 38.0"}, {"attributes":"Mot_cle Sonde"}, {"attributes":"Rang Rang 4"}]}, {"attributes": "Poste:  Rang Rang 4", "children": [{"attributes":"Debut_poste_Excel 39.0"}, {"attributes":"Fin_poste_Excel 39.0"}, {"attributes":"Mot_cle Soupape"}, {"attributes":"Rang Rang 4"}]}, {"attributes": "Poste:  Rang Rang 4", "children": [{"attributes":"Debut_poste_Excel 40.0"}, {"attributes":"Fin_poste_Excel 41.0"}, {"attributes":"Mot_cle Pressostat"}, {"attributes":"Rang Rang 4"}]}, {"attributes": "Poste:  Rang Rang 4", "children": [{"attributes":"Debut_poste_Excel 42.0"}]}]}]}]}]}]}]}]}

所以对于最终结果,我想要这样的东西(我们会说我想要的最后矩形在引号上,我们得到了:在->最终想要的结果之前),例如:"Poste:Rang范围1 |总计= 20 spaaaaace_on_the_rect->"过帐:范围1范围spaaaacceeeeeee_on_the_rect总计= 20.再次感谢您的帮助,也很抱歉我的英语不好;)

So for the final result , I want to have something like this (we will say that my final rect wanted is on the quote, we got : before -> the final result wanted), so for example: "Poste: Rang Rang 1 | Total =20 spaaaaace_on_the_rect" -> "Poste: Rang Rang 1 spaaaacceeeee_on_the_rect Total =20". Thanks you again for the help guys and sorry for my bad english ;)

推荐答案

正如我为

As I had created a Plunkr for the question you posted before, I've made changes to the same code here:

http://plnkr.co/edit/Pgqbn4eIECncuqhBVp6U?p=preview

相关代码更改:

更改了节点的文本添加逻辑

Changed the text adding logic to the nodes

nodeEnter.append("text")
  .attr("dy", 3.5)
  .attr("dx", 5.5)
  .each(function (d) {
    if(d.data.attributes.indexOf('|') > -1) {
      var beforeText = d.data.attributes.substr(0, d.data.attributes.indexOf('|')).trim(),
        afterText = d.data.attributes.substr(d.data.attributes.indexOf('|')+1, d.data.attributes.length).trim();

      d3.select(this).append('tspan').classed('beforetext', true).text(beforeText);
      var afterTextSpan = d3.select(this).append('tspan').classed('aftertext', true).text(afterText);

      // position aftertext
      var temp_text = svg_var.append('text').classed('temp_text', true).text(afterText);
      afterTextSpan.attr('x', barWidth-temp_text.node().getBBox().width+10)
      temp_text.remove();
    } else {
      d3.select(this).text(d.data.attributes); 
    }
  });

说明:

  1. 如果d.data.attributes不包含|,只需按原样设置文本.
  2. 如果确实包含|,请使用
  1. If d.data.attributes doesn't contain |, just set the text as is.
  2. If it does contain |, use substr to compute the strings before the | and after the | (set them to beforeText and afterText respectively.
  3. As you need two texts at different positions, I'd recommend using tspans and just changing the x positions (you could also do this by having 2 separate <text> elements)
  4. No need to position the beforeTextSpan as it's supposed to be on the left side which it gets to by default. But for positioning the afterTextTspan, I've used a temporary text to compute the width of the afterText and minus it from the barWidth to offset the tspan to the right side of the rect. (this logic is useful for larger texts).

顺便说一句,我使用了

And by the way, I've used the CSS I mentioned in my previous answer to align the SVGs. Hope this helps.

这篇关于在D3.Js中的rect中剪切文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆