I am trying to integrate Vue.js and D3.js. What I notice is sometimes the CSS classes don't really work on the svg elements. I am giving the snippet of the vue component below.
<template>
<div>
<h1>Hello world</h1>
<svg width="300" height="100" ref="barchart"></svg>
</div>
</template>
<script>
import * as d3 from "d3";
export default {
name: "LineChart",
mounted() {
d3.select("h1").attr("class","red-text")
var data = [10,20,15,30,60];
var barHeight = 20;
var bar = d3
.select(this.$refs.barchart)
.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("class","rect")
.attr("width", function(d) {
return d;
})
.attr("height", barHeight - 1)
.attr("transform", function(d, i) {
return "translate(0," + i * barHeight + ")";
});
}
};
</script>
<style scoped>
.rect{
fill: blue;
}
.red-text{
color:red;
}
</style>
Its output is obtained as :-
scoped css output
But as sson as I remove the scoped attribute, the code works fine. New output :-
global css output
Thanks in advance!
Scoped styles work by vue assigning a unique attribute to dom elements, and then adjusting the style rules by adding an extra criteria for elements to have that attribute. Example in vue guide. However, since elements dynamically created with d3 aren't managed by vue (since they aren't part of the template), it doesn't work out of the box. One way to solve this, is to to use deep selector (e.g. svg >>> .rect { ... }
), which doesn't attach the additional unique attribute criteria for the child elements.
If you just want to color the bars you don't need explicit css. You can just set:
.style("fill", function(d) { return 'blue'; })
on your bar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With