Reputation: 290
I have a packed circles graph (see this jsfiddle) where the circles have a black stroke on hover. What I would like is to use the CSS property mix-blend-mode: multiply
to change the circle border on hover.
Here is an example of what I want when the circle is selected or when we hover over the circle. The stroke is a darker shade of the fill color. I do not want to define each stroke color individually, because they are dynamically generated.
Can I use this CSS property combined with d3.js
circles so that only the stroke has the mix-blend-mode property ? Note that I'm using version 4 of d3.js
(d3.v4.min.js).
Upvotes: 0
Views: 1062
Reputation: 96
bit late here. was looking for nearly the same problem (to use mix-blend-mode only for the stroke, not the fill, but this doesnt work this way). anyway, saw your prob.. i'm not into d3.js, but maybe this helps after 2years:
you define the fill colors in your js (they are not dynamically), so best way is, to define there also the stroke colors.
in your js, i added a second color array 'my_colors_stroke' and placed beneath after the fill style a stroke style. also set in your css the default stroke-width to 0.
this here is a quick n dirty solution, but would recommend you to look at d3.js bubble docs because they have a slightly different approach to build bubbles, which looks easier.
var data = {
"name": "Main",
"children": [{
"id": "0",
"group": 0,
"name": "Group0",
"children": [{
"id": "0_0",
"name": "Subgroup_0_0",
"subgroup": 0,
"group": 0,
"children": [{
"node": 0,
"id": "0_0_0",
"stk_id": 247,
"stk_names": ["Person1"],
"name": "Person1",
"size": 0.5
},
{
"node": 1,
"id": "0_0_1",
"stk_id": 3309,
"stk_names": ["Person2"],
"name": "Person2",
"size": 0.5
}
]
}]
},
{
"id": "1",
"group": 1,
"name": "Group1",
"children": [{
"id": "1_1",
"name": "Subgroup_1_1",
"subgroup": 1,
"group": 1,
"children": [{
"node": 0,
"id": "1_1_0",
"stk_id": 285,
"stk_names": ["Person3"],
"name": "Person3",
"size": 0.5
}
]
}]
}
]
}
var my_colors = ["#FFD753", "#FF9D51"];
var my_colors_stroke = ["#efc743", "#ef8d41"];
var size = 500;
console.log("Variables set");
var svg = d3.select(".circles").append("svg")
.attr("class", "circle_packed")
.attr("id", "circle_packed")
.attr("width", size)
.attr("height", size);
console.log("Initialized svg");
var g = svg.append("g");
var pack = d3.pack().size([size , size ]).padding(5);
var root = d3.hierarchy(data)
.sum(function(d) { return d.size; })
.sort(function(a, b) { return b.value - a.value; });
console.log("Initialized pack");
var nodes = pack(root).descendants();
console.log(nodes);
var circle = g.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("class", function(d) {return d.parent ? (d.children ? "node " : "node node--leaf ") : "root "; })
.attr("id", function(d) {return "node_"+d.data.id;})
.attr("r", function(d) { return d.r; })
.style("fill", function(d) {
if(d.depth==2){
return my_colors[d.data.group];
} else {
return null;
}
})
.style("stroke", function(d) {
if(d.depth==2){
return my_colors_stroke[d.data.group];
} else {
return null;
}
});
var text = g.selectAll("text")
.data(nodes.filter(function(d){return d.depth==2}))
.enter().append("text")
.attr("class", "length-label")
.attr("id", function(d){ return "numSTK-"+d.data.id })
.text(function(d) { return d.data.children.length; })
.attr("text-anchor","middle")
;
g.selectAll("circle").on("click", function(d) {
this.classList.toggle("node-selected");
});
var node = g.selectAll("circle,text");
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
.circles{
width:100%;
background-color: #fff;
padding: 15px;
}
.root {
fill: #eee;
}
.node {
cursor: pointer;
fill: #e6e6e6;
overflow: hidden;
stroke-width: 0px;
}
.node:hover {
stroke: #000;
fill: #fff;
stroke-width: 8px;
}
.node-selected {
stroke:#000;
}
.node.node--leaf {
fill: #fff;
display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="circles" id="circles">
Upvotes: 0
Reputation: 1787
You could use :hover in your CSS on your circle, and within that set the stroke colour to black. See the circle on the left in the snippet below.
mix-blend-mode can be applied to the circle, but not sure how you would get a black stroke using that method. See the circle on the right in the snippet below. Also, mix-blend-mode isn't supported in all browsers.
body {
background: grey;
}
circle {
fill: orange;
stroke: DarkOrange;
stroke-width: 2px;
}
circle.stroke-color:hover {
stroke: black;
}
circle.mix-blend-mode:hover {
mix-blend-mode: multiply;
}
<svg width="500" height="500">
<circle class="stroke-color" cx="100" cy="75" r="50"/>
<circle class="mix-blend-mode" cx="300" cy="75" r="50"/>
</svg>
Upvotes: -1