简体   繁体   中英

Using different classes for different links in d3 js in tree layout

I am using d3 collapsible layout to make a collapsible tree. I want the links in the tree to have different colors according to json data.

The json data is

    {"root":{
 "name": "A",
 "branchid" : 2,
 "active" : true,
 "activecount" : 3, 
 "children": [
  {
   "name": "Data1",
   "branchid" : 2,
   "active" : false,
   "activecount" : 3, 
   "children": [
    {
     "name": "C",
     "branchid" : 2,
     "active" : true,
     "activecount" : 3, 
     "children": [
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3}
     ]
    },
    {
     "name": "C",
     "branchid" : 2,
     "active" : true,
     "activecount" : 3,
     "children": [
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3}
     ]
    },
    {
     "name": "C",
     "branchid" : 2,
     "active" : false,
     "activecount" : 3,
     "children": [
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3}
     ]
    }
   ]
  },
  {
   "name": "Data2",
   "branchid" : 2,
   "active" : true,
   "activecount" : 3,
   "children": [
    {"name": "D","branchid" : 2, "active" : true,"activecount" : 3},
    {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
    {
     "name": "C",
     "branchid" : 2,
     "active" : false,
     "activecount" : 3,
     "children": [
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : false,"activecount" : 3},
      {"name": "D","branchid" : 2, "active" : true,"activecount" : 3}
     ]
    },
    {"name": "C","branchid" : 2, "active" : false,"activecount" : 3},
    {"name": "C","branchid" : 2, "active" : false,"activecount" : 3},
    {"name": "C","branchid" : 2, "active" : false,"activecount" : 3},
    {"name": "C","branchid" : 2, "active" : true,"activecount" : 3},
    {"name": "C","branchid" : 2, "active" : false,"activecount" : 3},
    {"name": "C","branchid" : 2, "active" : true,"activecount" : 3},
    {"name": "C","branchid" : 2, "active" : true,"activecount" : 3},
    {"name": "C","branchid" : 2, "active" : false,"activecount" : 3},
    {"name": "C","branchid" : 2, "active" : true,"activecount" : 3}
   ]
  }
 ]
}}

I want the link to have activebranch css class if the active property of target node is true, otherwise it should have link css class.

.activebranch{
  fill: none;
  stroke: #000;
  stroke-width: 3.5px;
  cursor: pointer;
}

.link{
   fill: none;
   stroke: #bbb;
   stroke-width: 3.5px;
   cursor: pointer;
}

I am using following code to do this, but it dosen't work.

 var link = svg.selectAll("path.link")
              .data(links, function(d) {
                  if(d.target.active == "false")
                    return d.target.id; 
                });
          var activelink = svg.selectAll("path.activebranch")
                  .data(links, function(d){
                      if(d.target.active == "true")
                        return  d.target.id;
                  });

          // Enter any new links at the parent's previous position.
          link.enter().insert("path", "g")
              .attr("class", "link")
              .attr("d", function(d) {
                var o = {x: source.x0, y: source.y0};
                return diagonal({source: o, target: o});
              })
              .on("click", TimeLine);

            activelink.enter().insert("path", "g")
              .attr("class", "activebranch")
              .attr("d", function(d) {
                var o = {x: source.x0, y: source.y0};
                return diagonal({source: o, target: o});
              })
              .on("click", TimeLine);

          // Transition links to their new position.
          link.transition()
              .duration(duration)
              .attr("d", diagonal);

          activelink.transition()
              .duration(duration)
              .attr("d", diagonal);

          // Transition exiting nodes to the parent's new position.
          link.exit().transition()
              .duration(duration)
              .attr("d", function(d) {
                var o = {x: source.x, y: source.y};
                return diagonal({source: o, target: o});
              })
              .remove();
           activelink.exit().transition()
              .duration(duration)
              .attr("d", function(d) {
                var o = {x: source.x, y: source.y};
                return diagonal({source: o, target: o});
              })
              .remove();

I am using css class activelink for those links which have "active" : true and css class link which have "active" : false .

Based on your fiddle I created this .

To make it work, I first changed the raw json link, and then I added a sample additional class:

.link2 {
    stroke: red;
}

So when I add a link (on enter ), I simply:

link.enter().insert("path", "g")
    .attr("class", function (d) {
        var myClass = (d.target.name.length > 7 ? "" : " link2");
        return "link" + myClass;
    })
    ...etc

so I make sure the base class link is still there, and if a certain criteria is met (in our case here: if the name of the target node is > 7 in length) I add a class (or not). So in our case, we now have certain red links, based on the data in the JSON.

I hope this gets you started with your own data!

(add a console.log(d) in the function pasted above, to see the data that you have on the link).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM