Reputation: 83
I tried implementing the on-click function in d3. But the coloration of node is not happening as I have expected.
`var node = svg.selectAll('.node')
.data(force.nodes())
.enter().append('circle')
.attr('class', 'node')
.on("click", clicked)
.attr('r', width*0.03);
function clicked(event, d) {
if (event.defaultPrevented) return; // dragged
d3.select(this).transition()
.attr("fill", "black")
.attr("r", width * 0.2)
.transition()
.attr("r", width*0.03)
`
I tried to implement this code, but the color is not changing from the given color to black(as described in the clicked func.)
<style> .node{ fill: blue; stroke: black; stroke-width: 2px; }
Here I have described the original color of the node
Here is the whole code snippet
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node{
fill: blue;
stroke: black;
stroke-width: 2px;
}
.link{
stroke-width: 2px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var width = 640,
height = 480;
var links = [
{source: 'Rohit', target: 'Deep'},
{source: 'Deep', target: 'Deepa'},
{source: 'Deepa', target: 'Rohit'},
];
var nodes = {};
//adding to nodes
links.forEach(function(link){
link.source = nodes[link.source] ||
(nodes[link.source] = {name: link.source});
link.target = nodes[link.target] ||
(nodes[link.target] = {name: link.target});
});
//adding svg to body
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
var defs = svg.append('defs');
var gradient = defs
.append('linearGradient')
.attr('id', 'svgGradient')
.attr('x1', '0%')
.attr('x2', '10%')
.attr('y1', '0%')
.attr('y2', '10%');
gradient
.append('stop')
.attr('class', 'start')
.attr('offset', '0%')
.attr('start-color', 'red')
.attr('start-opacity', 1);
gradient
.append('stop')
.attr('class', 'end')
.attr('offset', '100%')
.attr('stop-color', 'blue')
.attr('stop-opacity', 1);
var force = d3.layout.force()
.size([width, height])
.nodes(d3.values(nodes))
.links(links)
.on("tick", tick)
.linkDistance(300)
.start();
var link = svg.selectAll('.link')
.data(links)
.enter().append('line')
.attr('class', 'link')
.attr('stroke', 'url(#svgGradient)');
var node = svg.selectAll('.node')
.data(force.nodes())
.enter().append('circle')
.attr('class', 'node')
.on("click", clicked)
.attr('r', width*0.03);
function clicked(event, d) {
if (event.defaultPrevented) return; // dragged
d3.select(this).transition()
.attr("fill", "black")
.attr("r", width * 0.2)
.transition()
.attr("r", width*0.03)
//.attr("fill", d3.schemeCategory10[d.index % 10]);
}
//define the tick func.
function tick(e){
node
.attr('cx', function(d){
return d.x;
})
.attr('cy', function(d){
return d.y;
})
.call(force.drag);
link
.attr('x1', function(d){
return d.source.x;
})
.attr('y1', function(d){
return d.source.y;
})
.attr('x2', function(d){
return d.target.x;
})
.attr('y2', function(d){
return d.target.y;
})
}
</script>
</body>
Upvotes: 1
Views: 53
Reputation: 36512
According to at least some documentation (e.g. https://www.d3indepth.com/transitions/) the color of the node is set in CSS using style, and if you use your browser's devtools inspect facility you can see that the blue is indeed set through settings for the class node.
Therefore change that attr to a style.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
fill: blue;
stroke: black;
stroke-width: 2px;
}
.node.visited {
fill: red;
}
.link {
stroke-width: 2px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var width = 640,
height = 480;
var links = [{
source: 'Rohit',
target: 'Deep'
},
{
source: 'Deep',
target: 'Deepa'
},
{
source: 'Deepa',
target: 'Rohit'
},
];
var nodes = {};
//adding to nodes
links.forEach(function(link) {
link.source = nodes[link.source] ||
(nodes[link.source] = {
name: link.source
});
link.target = nodes[link.target] ||
(nodes[link.target] = {
name: link.target
});
});
//adding svg to body
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
var defs = svg.append('defs');
var gradient = defs
.append('linearGradient')
.attr('id', 'svgGradient')
.attr('x1', '0%')
.attr('x2', '10%')
.attr('y1', '0%')
.attr('y2', '10%');
gradient
.append('stop')
.attr('class', 'start')
.attr('offset', '0%')
.attr('start-color', 'red')
.attr('start-opacity', 1);
gradient
.append('stop')
.attr('class', 'end')
.attr('offset', '100%')
.attr('stop-color', 'blue')
.attr('stop-opacity', 1);
var force = d3.layout.force()
.size([width, height])
.nodes(d3.values(nodes))
.links(links)
.on("tick", tick)
.linkDistance(300)
.start();
var link = svg.selectAll('.link')
.data(links)
.enter().append('line')
.attr('class', 'link')
.attr('stroke', 'url(#svgGradient)');
var node = svg.selectAll('.node')
.data(force.nodes())
.enter().append('circle')
.attr('class', 'node')
.on("click", clicked)
.attr('r', width * 0.03);
function clicked(event, d) {
if (event.defaultPrevented) return; // dragged
d3.select(this).transition()
.style("fill", "black")
.attr("r", width * 0.2)
.transition()
.attr("r", width * 0.03)
//.attr("fill", d3.schemeCategory10[d.index % 10]);
}
//define the tick func.
function tick(e) {
node
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.call(force.drag);
link
.attr('x1', function(d) {
return d.source.x;
})
.attr('y1', function(d) {
return d.source.y;
})
.attr('x2', function(d) {
return d.target.x;
})
.attr('y2', function(d) {
return d.target.y;
})
}
</script>
</body>
</html>
Upvotes: 1