new Vue({
el: "#app",
data() {
return {
index: 0,
data: [
[{
key: "Jan",
value: 5787
},
{
key: "Feb",
value: 6387
},
{
key: "Mrt",
value: 7375
},
{
key: "Apr",
value: 6220
},
{
key: "Mei",
value: 6214
},
{
key: "Jun",
value: 5205
},
{
key: "Jul",
value: 5025
},
{
key: "Aug",
value: 4267
},
{
key: "Sep",
value: 6901
},
{
key: "Okt",
value: 5800
},
{
key: "Nov",
value: 7414
},
{
key: "Dec",
value: 6547
}
],
[{
key: "Jan",
value: 2562
},
{
key: "Feb",
value: 3882
},
{
key: "Mrt",
value: 2323
},
{
key: "Apr",
value: 1283
},
{
key: "Mei",
value: 3526
},
{
key: "Jun",
value: 4578
},
{
key: "Jul",
value: 3848
},
{
key: "Aug",
value: 3564
},
{
key: "Sep",
value: 2436
},
{
key: "Okt",
value: 2536
},
{
key: "Nov",
value: 2733
},
{
key: "Dec",
value: 3172
}
]
]
}
},
mounted() {
// set the dimensions and margins of the graph
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 30
},
width = 500 - margin.left - margin.right;
this.height = 200 - margin.top - margin.bottom;
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
this.svg = d3
.select("#my_dataviz")
.append("svg")
.attr(
"viewBox",
`0 0 ${width + margin.left + margin.right} ${this.height +
margin.top +
margin.bottom}`
)
.attr("preserveAspectRatio", "xMinYMin")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// set the ranges
this.xScale = d3
.scalePoint()
.range([0, width])
.domain(
this.data.map(function(d) {
return d.key;
})
)
.padding(0.5);
this.yScale = d3.scaleLinear().rangeRound([this.height, 0]);
this.yScale.domain([0, 7000]);
// Draw Axis
this.xAxis = d3.axisBottom(this.xScale);
this.xAxisDraw = this.svg
.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${this.height})`);
this.yAxis = d3
.axisLeft(this.yScale)
.tickValues([0, 7000])
.tickFormat(d => {
if (d > 1000) {
d = Math.round(d / 1000);
d = d + "K";
}
return d;
});
this.yAxisDraw = this.svg.append("g").attr("class", "y axis");
this.update(this.data[this.index]);
},
methods: {
swapData() {
if (this.index === 0) this.index = 1;
else this.index = 0;
this.update(this.data[this.index]);
},
update(data) {
// Update scales.
this.xScale.domain(data.map(d => d.key));
this.yScale.domain([0, 7000]);
// Set up transition.
const dur = 1000;
const t = d3.transition().duration(dur);
// Update line.
this.line = this.svg.selectAll(".line").data([data], d => d.key)
this.line = this.line
.data([data], d => d.key)
.join(
enter => {
enter
.append("path")
.attr("class", "line")
.attr("fill", "none")
.attr("stroke", "#206BF3")
.attr("stroke-width", 4)
.attr(
"d",
d3
.line()
.x(d => {
return this.xScale(d.key);
})
.y(() => {
return this.yScale(0);
})
)
.transition(t)
.attr(
"d",
d3
.line()
.x(d => {
return this.xScale(d.key);
})
.y(d => {
return this.yScale(d.value);
})
);
},
update => {
update.transition(t).attr(
"d",
d3
.line()
.x(d => {
return this.xScale(d.key);
})
.y(d => {
return this.yScale(d.value);
})
);
},
exit => exit.remove()
);
// Update Axes.
this.yAxis.tickValues([0, 7000]);
if (data.length > 12) {
this.xAxis.tickValues(
data.map((d, i) => {
if (i % 3 === 0) return d.key;
else return 0;
})
);
} else {
this.xAxis.tickValues(
data.map(d => {
return d.key;
})
);
}
this.yAxis.tickValues([0, 7000]);
this.xAxisDraw.transition(t).call(this.xAxis.scale(this.xScale));
this.yAxisDraw.transition(t).call(this.yAxis.scale(this.yScale));
}
}
})
<div id="app">
<button @click="swapData">Swap</button>
<div id="my_dataviz" class="flex justify-center"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://d3js.org/d3.v6.js"></script>