I've got a Vue component and inside mounted
method I have this:
this.el = d3.select(this.$el);
this.svg = this.el.select('svg')
.attr('width', mainSvgPos.svgWidth)
.attr('height', mainSvgPos.svgHeight)
.attr('viewBox', "0 0 " + mainSvgPos.svgWidth + " " + mainSvgPos.svgHeight)
.attr('style',"position:absolute;left:0;top:20px;width:100%;height:100%")
this.chart = this.svg.select('g.chart').attr('transform', "translate(" + chartCenter.leftOffset + ", " + chartCenter.topOffset + ")")
I'm testing this component with jest
and vue-test-util
My test looks like this:
describe('gauge', () => {
const wrapper = shallow(gauge, {
propsData: ...some data,
})
it('renders correctly', () => {
expect(wrapper.vm.$el).toMatchSnapshot()
});
})
When it runs for the first time, as expected, it creates the shapshot. In this snapshot, I have the parent svg
element with all attributes set correctly (width, height, viewBox, style). However the g.chart
element does not contain any attributes (it should contain transform
). The mounted method creates a bunch of other elements using D3 syntax after that (I have not pasted them here)...none of that gets in the snapshot.
So my question is what happens in this.svg = this.el.select('svg')...
that prevents the snapshot from being created properly and how do I fix that.
I've tried nextTick
, jest.useFakeTimers()
, shallow
mounting, nothing gives me what I want.
Thanks
I did several things to fix this:
1) No longer using d3.select.attr
to modify svg
and g.chart
attributes in mounted. I modified those attributes via props instead
2) In the original code, after this line:
this.chart = this.svg.select('g.chart').attr('transform', "translate(" + chartCenter.leftOffset + ", " + chartCenter.topOffset + ")")
I had a gradient arc generation via d3:
const arc = d3.arc()
.innerRadius(this.arc_radius - this.chart_inset - this.bar_width)
.outerRadius(this.arc_radius - this.chart_inset)
.startAngle(function (d) {
return d.startAngle;
}).endAngle(function (d) {
return d.endAngle;
});
d3.select(this.$el).append('g').selectAll('path').data(this.pieces).enter()
.append('path').attr("d", arc)
.attr("stroke-width", 1).attr("stroke", function (d) {
return d.fill;
}).attr("fill", function (d) {
return d.fill;
});
This also didn't get to the snapshot. Even after point 1 above was done. I moved this gradient arc generation into a new component's mounted
method. And suddenly it started working. shallow
on the new component created the markup correctly. Notice how in the new component, I still use d3.selectAll
...but this time it works as expected
So this does not answer the previous issue but maybe refactoring the component's mounted
method a bit will help.