這次要來練習用 D3
搭配 Vue
做多組動態的 SVG
直條圖囉~
前面幾篇有講過的原理這裡就不再次解釋,我們直接從繪製直條開始說起。
繪製直條
這邊直條圖外面包了兩次 transition-group
是因為第一次進來頁面的時候,並不會呈現動畫,所以為了 Fixed 這個 Bug 所以外面又包了一次 transition-group
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
<transition-group tag="g" name="growBar"> <transition-group tag="g" name="growBar" class="bar" v-for="(group, key) in bar" :key="`${key}${group.rect.height}${group.rect.x}`"> <rect v-for="(r, k) in group.rect" :key="`${k}${r.height}${r.x}`" :fill="group.color" :x="r.x" :y="r.y" :width="r.width" :height="r.height" v-on:mouseover="showTooltip(key, k, $event)" v-on:mouseout="hiddenTooltip" ></rect> </transition-group> </transition-group>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| .growBar-enter-active { transition: transform 0.7s, opacity 1s; } .growBar-enter {
transform: scaleY(0.55) translateY(-12%); opacity: 0; } ......
.chartContain { .... .chart { .... .chartWrap { ....
.bar { transform-origin: 50% 100%; rect { transform-origin: 50% 100%; } } } } }
|
直條寬度(barWidth)和個別 x 座標這兩個比較難懂的地方,在後面會用圖解的方式說明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| color() { return d3.scaleOrdinal(d3.schemeCategory20c); }, barWidth() {
return ( (this.chart.width / (this.valueLength + 1) * this.valueLength - this.chart.gap * this.data.length) / (this.valueLength * this.data.length) ); },
bar() { let rectArray = [];
if (this.valueLength) { this.data.forEach((group, index) => { let rectGroup = [];
group.value.forEach((e, i) => { rectGroup.push({
x: this.xScale(i + 1) - this.barWidth * this.data.length / 2 + this.barWidth * index, y: this.yScale(e.number), width: this.barWidth, height: this.chart.height - this.yScale(e.number) }); });
rectArray.push({ rect: rectGroup, color: this.color(index) }); }); }
return rectArray; },
|
直條寬度(barWidth)
剩下可放圖的地方 = 圖表寬度 - 左右的間距 (大約是x軸寬除上總刻數+1)
扣掉長條圖中間的間隔
剩下的寬度分給所有長條
直條x座標
把群組直條往左推整體的一半
依個別順序向右平移
全部畫好的樣子如下圖,可以去 Github 查看完整程式碼喔!也可以在這裡查看直條圖的 Demo,我們下回見~