Quantcast
Channel: User i alarmed alien - Stack Overflow
Viewing all articles
Browse latest Browse all 42

Answer by i alarmed alien for Add event listener per nodes level on d3 chart

$
0
0

If you want to collapse all nodes except the root and the first set of children, you can run the following code:

root.children.forEach(collapse);

This recursively applies the collapse function to all the children of the root.

There is already a click event listener on your nodes, which you can alter according to your plans. Adding listeners for mouseover and mouseout events is very simple:

var nodeEnter = node.enter().append("g").attr("class", "node").on("click", click).on('mouseover', mouseover) // mouseover!.on('mouseout', mouseout)   // mouseout!

You then need to add functions that will define the actions that occur. Here are a couple of sample functions:

// `d` is the data item attached to the DOM node;// `this` is the node that triggered the event (`g.node`)function mouseover(d) {  // select the `rect` node that is the child of the DOM node that triggered the event  d3.select(this).select('rect').style('fill', function(d){    // depending on the level of the node, give it one of these tacky colours    if (d.depth === 0) {      return 'deepskyblue'    } else if (d.depth === 1) {      return 'deeppink'    } else if (d.depth === 2) {      return 'goldenrod'    }    return 'papayawhip' // default  })}function mouseout(d) {  // select the rect element  d3.select(this).select('rect')    // if the node has collapsed children, turn it light blue; otherwise turn it red    .style('fill', d => d._children ? "lightsteelblue" : "red")}

You can also add extra functionality to the click function in a similar manner.

Here are the event listeners in action:

var pubs = {"name": "TOOLS","children": [{"name": "Localization","children": [{"name": "FRANCE"        },        {"name": "SUISSE"        },        {"name": "USA"        },        {"name": "UK"        }      ]    },    {"name": "Test","children": [{"name": "FRANCE"        },        {"name": "SUISSE"        },        {"name": "USA"        },        {"name": "UK"        }      ]    },    {"name": "Oh My God","children": [{"name": "FRANCE"        },        {"name": "SUISSE"        },        {"name": "USA"        },        {"name": "UK"        }      ]    },    {"name": "Another Tool","children": [{"name": "FRANCE"        },        {"name": "SUISSE"        },        {"name": "USA"        },        {"name": "UK"        }      ]    },    {"name": "And Again","children": [{"name": "FRANCE"        },        {"name": "SUISSE"        },        {"name": "USA"        },        {"name": "UK"        }      ]    },    {"name": "And Again","children": [{"name": "FRANCE"        },        {"name": "SUISSE"        },        {"name": "USA"        },        {"name": "UK"        }      ]    },    {"name": "Production","children": [{"name": "FRANCE"        },        {"name": "SUISSE"        },        {"name": "USA"        },        {"name": "UK"        }      ]    },    {"name": "Audio","children": [{"name": "AUT-11"        },        {"name": "AUT-12"        }      ]    },    {"name": "Animation","children": [{"name": "AUT-11"        },        {"name": "AUT-12"        }      ]    },    {"name": "Tags","children": [{"name": "AUT-11"        },        {"name": "AUT-12"        }      ]    }  ]};var diameter = 800;var margin = {    top: 20,    right: 120,    bottom: 20,    left: 120  },  width = diameter,  height = diameter;var i = 0,  duration = 350,  root;var tree = d3.layout.tree()  .size([360, diameter / 2 - 80])  .separation(function(a, b) {    return (a.parent == b.parent ? 1 : 1) / a.depth;  });var diagonal_extras = {  path: {    // diagonal line    direct: function(p) {        return [p.source, p.target];      }      // this is also the default path in radial trees      ,    l_shape: function(p) {        return [p.source, {          x: p.target.x,          y: p.source.y        }, p.target];      }      ,    l_shape_2: function(p) {        return [p.source, {          x: p.source.x,          y: p.target.y        }, p.target];      }      ,    dogleg: function(p) {        return [p.source,          {            x: p.source.x,            y: (p.source.y + p.target.y) / 2          },          {            x: (p.source.x + p.target.x) / 2,            y: (p.source.y + p.target.y) / 2          },          {            x: p.target.x,            y: (p.source.y + p.target.y) / 2          },          p.target        ];      }      ,    dogleg_2: function(p) {      return [p.source,        {          x: (p.source.x + p.target.x) / 2,          y: p.source.y        },        {          x: (p.source.x + p.target.x) / 2,          y: (p.source.y + p.target.y) / 2        },        {          x: (p.source.x + p.target.x) / 2,          y: p.target.y        },        p.target      ];    }  }  ,  polar_obj_to_cart: function(pt) {      var angle = pt.x / 180 * Math.PI;      return [pt.y * Math.cos(angle), pt.y * Math.sin(angle)];    }    ,  polar_coords_to_cart: function(xy) {    var angle = xy[0] / 180 * Math.PI;    return [xy[1] * Math.cos(angle), xy[1] * Math.sin(angle)];  }}diagonal_extras.right_angle = function() {  var projection = d3.svg.diagonal().projection(),    path_type = 'dogleg';  function diagonal(d) {    return diagonal.path_maker(diagonal_extras.path[diagonal.path_type()](d));  }  diagonal.path_maker = function(pathData) {    return "M"+ pathData.map(projection).join('');  };  diagonal.valid_path_types = function() {    return Object.keys(diagonal_extras.path);  };  diagonal.path_type = function(x) {    if (!arguments.length) {      return path_type;    }    if (diagonal_extras.path[x]) {      path_type = x;      return diagonal;    }    throw new Error(x +' is not a valid path type');  };  diagonal.projection = function(x) {    if (!arguments.length) {      return projection;    }    projection = x;    return diagonal;  };  diagonal.path = function(x) {    if (!arguments.length) {      return path;    }    path = x;    return diagonal;  };  diagonal.draw = function(d) {    return diagonal(d);  };  return diagonal;}diagonal_extras.radial = function() {  var diagonal = diagonal_extras.right_angle(),    projection = function(pt) {      return [pt.x, pt.y];    };  diagonal.path_type('direct');  diagonal.projection = function(x) {    if (!arguments.length) {      return projection;    }    projection = x;    return diagonal;  };  diagonal.path_maker = function(pathData) {    var projected = pathData.map(function(x) {        return projection(x);      }),      pl = projected.length,      points, prev_angle;    // direct link:    if (2 === pl) {      return 'M'+ projected.map(function(x) {        return diagonal_extras.polar_coords_to_cart(x);      }).join('');    }    points = projected.map(function(obj) {      return {        angle: obj[0] / 180 * Math.PI,        radius: obj[1]      };    });    return "M"+ points.map(function(pt) {      var str = '';      if (prev_angle) {        if (prev_angle === pt.angle) {          // draw a straight line          str = 'L';        } else {          // draw an arc to the new radius and angle          str = 'A'+ pt.radius +','+ pt.radius            // x axis rotation+" 0 "            // large arc flag+" 0,"            // sweep+            (pt.angle > prev_angle ? 1 : 0) +"";        }      }      prev_angle = pt.angle;      return str + pt.radius * Math.cos(pt.angle) +","+ pt.radius * Math.sin(pt.angle);    }).join('');  };  return diagonal;}var diagonal = diagonal_extras.radial()  .path_type('dogleg')  .projection(function(d) {    return [d.x - 90, d.y];  });var svg = d3.select("body").append("svg")  .attr("width", width)  .attr("height", height)  .append("g")  .attr("transform", "translate("+ diameter / 2 +","+ diameter / 2 +")");var rect = {  l: 95,  w: 20}root = pubs;root.x0 = height / 2;root.y0 = 0;root.children.forEach(collapse); // start with all children collapsedupdate(root);d3.select(self.frameElement).style("height", "800px");function update(source) {  // Compute the new tree layout.  var nodes = tree.nodes(root),    links = tree.links(nodes),    offset = nodes[0].x;  // Normalize for fixed-depth.  nodes.forEach(function(d) {    d.y = d.depth * 150;  });  // Normalise angles so that the root is horizontal  if (nodes[0].x > 180) {    nodes[0].x = nodes[0].x - 90  } else {    nodes[0].x = nodes[0].x + 90  }  // Update the nodes…  var node = svg.selectAll("g.node")    .data(nodes, function(d) {      return d.id || (d.id = ++i);    });  // Enter any new nodes at the parent's previous position.  var nodeEnter = node.enter().append("g")    .attr("class", "node")    //.attr("transform", function(d) { return "rotate("+ (d.x - 90) +")translate("+ d.y +")"; })    .on("click", click)    .on('mouseover', mouseover)    .on('mouseout', mouseout)  nodeEnter.append("rect")    .attr("width", rect.l)    .attr("height", rect.w)    .attr("x", -rect.l / 2)    .attr("y", -rect.w / 2)    .style("fill", function(d) {      return d._children ? "lightsteelblue" : "red";    });  nodeEnter.append("text")    .attr("x", 0)    .attr("dy", ".35em")    .attr("text-anchor", "middle")    //.attr("transform", function(d) { return d.x < 180 ? "translate(0)" : "rotate(180)translate(-"+ (d.name.length * 8.5)  +")"; })    .text(function(d) {      return d.name;    })    .style("fill-opacity", 1e-6);  // Transition nodes to their new position.  var nodeUpdate = node.transition()    .duration(duration)    .attr("transform", function(d) {      return "rotate("+ (d.x - 90) +")translate("+ d.y +")";    })  // nodeUpdate.select("circle")  //     .attr("r", 4.5)  //     .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });  nodeUpdate.select("text")    .style("fill-opacity", 1)    .attr("transform", function(d) {      return d.x < 180 ? "translate(0)" : "rotate(180)";    });  // TODO: appropriate transform  var nodeExit = node.exit().transition()    .duration(duration)    //.attr("transform", function(d) { return "diagonal("+ source.y +","+ source.x +")"; })    .remove();  // nodeExit.select("circle")  //     .attr("r", 1e-6);  nodeExit.select("text")    .style("fill-opacity", 1e-6);  // Update the links…  var link = svg.selectAll("path.link")    .data(links, function(d) {      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      });    });  // Transition links to their new position.  link.transition()    .duration(duration)    .attr("d", function(d) {      return diagonal({        source: {          x: d.source.x,          y: d.source.y + rect.l / 2        },        target: {          x: d.target.x,          y: d.target.y - rect.l / 2        }      })    });  // 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();  // Stash the old positions for transition.  nodes.forEach(function(d) {    d.x0 = d.x;    d.y0 = d.y;  });}function mouseover(d) {  d3.select(this).select('rect').style('fill', function(d){    if (d.depth === 0) {      return 'deepskyblue'    } else if (d.depth === 1) {      return 'deeppink'    } else if (d.depth === 2) {      return 'goldenrod'    }    return 'papayawhip'  })}function mouseout(d) {  d3.select(this).select('rect').style('fill', d => d._children ? "lightsteelblue" : "red")}// Toggle children on click.function click(d) {  if (d.children) {    d._children = d.children;    d.children = null;  } else {    d.children = d._children;    d._children = null;  }  update(d);}// Collapse nodesfunction collapse(d) {  if (d.children) {    d._children = d.children;    d._children.forEach(collapse);    d.children = null;  }}
.node {  cursor: pointer;}.node text {  font: 10px sans-serif;}.link {  fill: none;  stroke: #ccc;  stroke-width: 1.5px;}
<script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>

Viewing all articles
Browse latest Browse all 42

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>