score:3
There are a few ways to approach this, but this is the easiest one I can think of as of now.
Note that there are two paths between Assess
and Create QoS Degradation Report
in your bl.ock with equal but opposite values (as they are both a source and a target for each other). One of them is laid exactly on top the other, giving them the appearance of a single path. That's why the link between these two nodes is somewhat jagged, while the others are smooth. Perhaps we can take advantage of this.
If you adjust the definitions for link--source
and link--target
in your CSS to have an opacity value of less than 1, a partially transparent source link will overlap a partially transparent target link, giving the appearance of a "new", different color.
As for the node color, create a new CSS class node--both
with the "new" color, and apply it to the node if both n.source
and n.target
are true in the mousovered
function.
node
.classed("node--both", function(n) { return n.source && n.target; })
.classed("node--target", function(n) { return n.target; })
.classed("node--source", function(n) { return n.source; });
It's not perfect, but here's a fiddle demonstrating this: http://jsfiddle.net/w2rfwokx/
The key is to choose the source and target link colors and opacity values appropriately (which I didn't do) so that you get a new color different enough from the source and target links and also the same color regardless of whether the source or the target link is "on top". In the current fiddle version, you can see that the colors slightly differ depending on which node is active. This thread or something similar might help.
You could also try manipulating the links
array to merge the two identical paths into one and adding an attribute to indicate that this is a source-and-target link and use this attribute later while processing.
Update: You have the right idea in your comment. The color trick was more of a hack anyway.
The links
array contains two items for the one path between the two-way import nodes. Let's remove one of them and also set an attribute in the other to indicate that this is a two-way import.
var unique_links = links.reduce(function(p,c) {
var index=p.map(function(d,i) { if(d.source===c.target && d.target===c.source) return i;}).shift();
if(!isNaN(index)) p[index].both=true; else p.push(c);
return p;
},[]);
Now unique_links
has only one element per edge and that one element has both=true
. Let's also pass the both
attribute along to the bundle layout.
link = link
.data(bundle(unique_links))
.enter().append("path")
.each(function(d) {
d.source = d[0],
d.target = d[d.length - 1],
d.both = unique_links.filter(function(v) { if (v.source===d.source && v.target===d.target) return v.both; }).shift();
})
.attr("class", "link")
.attr("d", line);
The final step is to change the mouseovered
function to set a new CSS class with a different color using both
:
function mouseovered(d) {
node
.each(function(n) { n.target = n.source = false; });
link
.classed("link--both", function(l) { if((l.target===d || l.source===d) && l.both) return l.source.source = l.source.target = l.target.source = l.target.target = true;})
.classed("link--target", function(l) { if (l.target === d && !l.both) return l.source.source = true; })
.classed("link--source", function(l) { if (l.source === d && !l.both) return l.target.target = true; })
.filter(function(l) { return l.target === d || l.source === d; })
.each(function() { this.parentNode.appendChild(this); });
node
.classed("node--both", function(n) { return n.target && n.source; })
.classed("node--target", function(n) { return n.target; })
.classed("node--source", function(n) { return n.source; });
}
And reset the classes in mouseouted
:
function mouseouted(d) {
link
.classed("link--both", false)
.classed("link--target", false)
.classed("link--source", false);
node
.classed("node--both", false)
.classed("node--target", false)
.classed("node--source", false);
}
Remember to define the new classes in CSS:
.link--both {
stroke: orange;
}
.node--both {
fill: orange;
}
Here's an updated fiddle with the complete code: http://jsfiddle.net/w2rfwokx/1/
Source: stackoverflow.com
Related Query
- D3 Dynamic hierarchical edge bundling - 2 way import
- Hierarchical edge bundling 2 way - link colour
- d3 js Hierarchical edge bundling Data Format
- d3.js combining Hierarchical Edge Bundling and Radial Reingold–Tilford Tree + data
- Hierarchical Edge Bundling d3 v4 - simplest 2 node example
- How to control the group node distance in Hierarchical Edge Bundling in D3.js
- D3.js hierarchical edge bundling coloring by group
- TypeError: n is undefined in D3.js , trying to replicate the Hierarchical Edge Bundling
- Hierarchical Edge Bundling from Force Layout in D3
- d3.js: Hierarchical Edge Bundling change curveBundle for each link separately
- D3 V4 Hierarchical Edge Bundling port from v3
- How to control the thickness of lines in the Hierarchical Edge Bundling chart?
- d3: Adding links to nodes in hierarchical edge bundling
- d3 v4 Hierarchical Edge Bundling
- How to highlight a source node and all its target nodes and corresponding links in d3 hierarchical edge bundling
- Understanding of Hierarchical Edge Bundling json dataset construction
- d3js: Add quantitative dimension to Hierarchical Edge Bundling
- Dark filled Links being displayed when downloading d3 hierarchical edge bundling visualization as PNG
- How to use D3 hierarchical edge bundling graph with Plotly
- d3.js Hierarchical Edge Bundling node color change on click
- Multilevel Hierarchical Edge Bundling
- D3.js Hierarchical Edge Bundling with straight edges
- Combine D3 Pie Chart and Hierarchical Edge Bundling
- Render D3 Hierarchical Edge Bundling
- d3: Hierarchical Edge Bundling with mouse click on links
- D3 Hierarchical Edge Bundling
- In Hierarchical edge bundling how to use json string instead of a json file?
- Is there a way to convert CSV columns into hierarchical relationships?
- What is the correct way to import and use d3 and its submodules in ES6?
- Correct Way to Import D3.js into an Angular 2 Application
More Query from same tag
- Adding new nodes to a clustered force layout
- D3.js conflict with Boostrap
- How to translate an Observable Notebook example into javascript?
- How to make a semi-circle in d3?
- Dimple.js line chart with composite axis, no links between points on series
- D3 collapsible tree - jumpy on zoom
- Javascript returns undefined when indexing into an array using a property of an object
- Removing data when clicking on canvas in d3
- .on("drag", function()) and .on("contextmenu", function()) does not work when used on the same code
- d3.js - How can I set the cursor to hand when mouseover these elements on SVG container?
- rendering issue in d3 radial bar chart with labels
- Draw imbricated blocks that are rotated and fliped with d3.js
- How to draw line charts with complex data structures in d3
- Add size to icicle visualization
- d3 - Search tree and highlight node and path for d3 v5
- Making D3 Bubble Charts Without Children Elements
- Keeping element order (selection.order) with exit transitions in d3
- How to add another axis in a parallel coordinate plot in d3
- Transform <g> attribute on map of d3.js
- D3.js - why mouseover and mouse out fired for each child elements?
- D3 managing multiple classes for multiple chart labels
- D3 - Add a raw symbol
- dimple.js plots the wrong values
- Maximum distance limit for D3 Force Layout?
- dagre-d3 js Zoom Fit to all contents
- Rect elements not transitioning to data point when button is clicked
- d3.js: reusable clipPath for multiple svg:text elements
- d3.js loop number as variable for
- how to do a complex crossfilter reduction
- How can I change the color of a circle created via d3 each time I click the mouse?