摘要:這篇學習筆記是入門篇的最后一部分,將前幾篇的內(nèi)容整合到一起,繪制帶過渡效果的柱狀圖,這次先給大家看一下結果圖。
這篇學習筆記是入門篇的最后一部分,將前幾篇的內(nèi)容整合到一起,繪制帶過渡效果的柱狀圖,這次先給大家看一下結果圖。
結果
前言先放結果圖是想反饋一下在整合基礎知識繪制完整柱狀圖遇到的幾個問題:
整個柱狀圖的布局,比如哪些元素包在一個
如果不采用translate,transform?翻轉height屬性的值,如何讓矩形正常方向顯示;
如何繪制文字;
如何為柱狀圖添加過渡效果;
坐標軸的位置如何確定,x軸如何劃分刻度,如何讓刻度顯示在矩形的正下方;
!!!! 接下來將逐個解決上述出現(xiàn)的問題!!!!
Problem1:柱狀圖的整體布局Solution
(1)為了繪制時,圖形四周留有空白區(qū)域,我們首先設置一個padding值; var padding={top:40,bottom:40,left:40,right:40};//定義間隔 (2)我們考慮在svg畫布上進行繪制,采用如下的結構進行繪圖:Problem2:如何按照垂直向上的方向顯示矩形
Solution
之前的幾篇文章我都是通過transform變換實現(xiàn)了矩形的翻轉,這篇文章介紹一個新的思路。
首先確定一個矩形需要四要素(x,y,width,height),同時我們需要注意,畫布的坐標軸方向為水平向右和垂直向下。height是我們數(shù)據(jù)可視化的展示部分,即數(shù)據(jù)的綁定部分,x,y確定了繪制矩形的左上角坐標。
這里提供一個思路:
如果按照正常垂直向下的方向繪制矩形時,要求矩形的bottom處在同一水平線上,y+height==固定值;也就是數(shù)據(jù)(height)大的部分,我們希望矩形的繪制起始點(y)的值較小,數(shù)據(jù)小(height)的部分,我們希望矩形的繪制起始點(y)的值較大。
因此我們可以通過定義比例尺完成這個功能,將dataset中大的數(shù)值,映射出range中小的數(shù)值。
//定義y方向比例尺 var yScale=d3.scaleLinear() .domain([0,d3.max(dataset)]) .range([height-padding.top-padding.bottom,0]); //定義y的值 .attr("y",function (d,i) { return yScale(d) }) //定義height .attr("height",function (d,i) { return height-padding.top-padding.bottom-yScale(d); }) 可以看出來‘y’+‘height’==height-padding.top-padding.bottom(這是一個固定的值)Problem3:如何繪制文字
Solution
在Problem1中已經(jīng)解決的布局方案問題,我們的方法是將矩形與文字包在一個g標簽下,所以繪制文字與繪制矩形的方法相同,在
(1)文字的顯示位置:x,y
(2)文本信息:text
(3)文字位置的偏移值:dx,dy
graph.append("text") .style("fill","pink") .attr("x",function(d,i){ return xScale(i); }) .text(function (d) { return d }) .attr("y",function (d,i) { return yScale(d); })Problem4:如何為柱狀圖添加過渡效果
Solution
為柱狀圖添加過渡效果,我們需要調用以下API:
.transition():為這個元素添加過渡;
.duration():設定元素從起始狀態(tài)到終止狀態(tài)的過渡時間;
.delay():設定元素執(zhí)行過渡效果的時間間隔;
.ease():設定過渡的動畫效果;
在為元素添加過渡效果時,初始狀態(tài),終止狀態(tài)尤為重要,柱狀圖為例分析一下元素的兩個狀態(tài):
明確柱形圖為每個矩形添加過渡時,只有兩個屬性值需要改變,一個是y的值,一個是height的值;
起始狀態(tài):柱狀圖的起始狀態(tài)非常好理解,就是矩形不顯示的狀態(tài),即y值設定為前文提到的固定值,height設定為0;
終止狀態(tài):柱狀圖的終止狀態(tài)應該是矩形元素和文字都可視化固定顯示出來,即為正常綁定元素時設定的相關屬性值。
//為矩形添加過渡效果 .attr("y",function (d) { var min=yScale.domain()[0]; return yScale(min); }) .attr("height",function(d,i){ return 0; }) .transition() .duration(2000) .delay(function(d,i){ return i*400; }) .ease(d3.easeBackOut) .attr("y",function (d,i) { return yScale(d) }) .attr("height",function (d,i) { return height-padding.top-padding.bottom-yScale(d); })Problem5:格式化顯示坐標軸
Solution
在開始學習坐標軸的時候,只實現(xiàn)了添加y軸,在這次完整柱狀圖實現(xiàn)中,嘗試添加x軸卻遇到了問題。在這個例子中我們一共綁定了8個數(shù)據(jù),那么如何讓x軸的刻度均勻的顯示在每個矩形的下方呢?
在定義x軸的時候我用了ScaleBand()這個方法:
//在range返回等差數(shù)列 var xScale=d3.scaleBand() .domain(d3.range(dataset.length)) .rangeRound([0,dataset.length*(rectWidth+(rectPadding/2))]); var xAxis=d3.axisBottom(xScale) .ticks(5);
既然比例尺返回一個等差數(shù)列,所以我們要求在柱狀圖區(qū)域,每個矩形和空白間隔這個整體是相同的,所以我的實現(xiàn)是每個矩形左右各是半個rectPadding。先設置x的值,然后width設置成矩形寬度減去半個間隔。(不理解的可以自己畫一張圖就可以了)
.attr("x",function (d,i) { return (i*rectWidth)+(i+1)*(rectPadding/2); }) .attr("width",rectWidth-rectPadding/2)
代碼部分
import * as d3 from "d3"; var dataset = [45, 70, 12, 79, 4, 127, 33, 150]; var width = 600;//svg畫布寬 var height = 600;//svg畫布高 var rectWidth = 50;//每個矩形的默認寬度 var rectPadding=10;//每個矩形間的間隔 var padding={top:40,bottom:40,left:40,right:40};//定義間隔 //定義畫布 var svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height) .style("background-color", "yellow"); //定義矩形比例尺 var yScale=d3.scaleLinear() .domain([0,d3.max(dataset)]) .range([height-padding.top-padding.bottom,0]); var yAxis=d3.axisLeft(yScale) .ticks(5); svg.append("g") .attr("transform",`translate(${padding.top},${padding.left})`) .call(yAxis); var xScale=d3.scaleBand() .domain(d3.range(dataset.length)) .rangeRound([0,dataset.length*(rectWidth+(rectPadding/2))]); var xAxis=d3.axisBottom(xScale) .ticks(5); svg.append("g") .attr("transform",`translate(${padding.left},${height-padding.top})`) .call(xAxis); //定義矩形 var g=d3.selectAll("svg") .append("g") .attr("transform",`translate(${padding.top},${padding.left})`); var graph=g.selectAll("rect") .data(dataset) .enter() .append("g"); graph.append("rect") .style("fill","blue") .attr("x",function (d,i) { return (i*rectWidth)+(i+1)*(rectPadding/2); }) .attr("width",rectWidth-rectPadding/2) .attr("y",function (d) { var min=yScale.domain()[0]; return yScale(min); }) .attr("height",function(d,i){ return 0; }) .transition() .duration(2000) .delay(function(d,i){ return i*400; }) //.ease(d3.easeBackOut) .attr("y",function (d,i) { return yScale(d) }) .attr("height",function (d,i) { return height-padding.top-padding.bottom-yScale(d); }) graph.append("text") .style("fill", "pink") .attr("x", function (d, i) { return (i * rectWidth) + (i + 1) * (rectPadding / 2); }) .attr("dx", 10) .attr("y", function (d) { var min = d3.min(dataset); return yScale(min) }) .text(function (d) { return d }) .transition() .duration(2000) .delay(function (d, i) { return i * 400; }) .attr("y", function (d, i) { return yScale(d); })附錄
接下來會寫進階篇的學習筆記
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100135.html
摘要:為了根據(jù)顯示刻度靈活變化寬高,而不是定死,特別是數(shù)據(jù)差異性很大的時候,我們希望圖表顯示范圍都在畫布里面,這時就會引入比例尺的概念來進行縮放。根據(jù)這些規(guī)則,會為我們返回一個比例尺函數(shù)。 這篇文章繼續(xù)介紹d3的基礎知識 比例尺 在繪制柱狀圖時,我們往往會定義很大的畫布,然而我們要可視化的數(shù)據(jù)確很小,這時會出現(xiàn)很多留白 的情況。為了根據(jù)顯示刻度靈活變化寬高,而不是定死,特別是數(shù)據(jù)差異性很大的...
摘要:數(shù)據(jù)可視化圖表圖表作為數(shù)據(jù)可視化最常見的表現(xiàn)形式之一,往往被以偏概全的認為圖表就是數(shù)據(jù)可視化。嚴格來說,數(shù)據(jù)可視化應該是連接數(shù)據(jù)與視覺的一個映射關系,將數(shù)據(jù)映射成人更容易感知其規(guī)律的可視化結果。 題目中的新一代是個相對的概念,事實上本文即將介紹的方法已經(jīng)有了生產(chǎn)環(huán)境可用的實現(xiàn)方案(這也側面佐證了其可行性),但考慮到此方法與現(xiàn)在大部分前端項目中所使用的數(shù)據(jù)可視化方案相比仍有一些優(yōu)勢,因此...
摘要:在文末,我會附上一個可加載的模型方便學習中文藝術字渲染用原生可以很容易地繪制文字,但是原生提供的文字效果美化功能十分有限。 showImg(https://segmentfault.com/img/bVWYnb?w=900&h=385); WebGL 可以說是 HTML5 技術生態(tài)鏈中最為令人振奮的標準之一,它把 Web 帶入了 3D 的時代。 初識 WebGL 先通過幾個使用 Web...
摘要:有一些表示常見圖形的對象稱為塊,完整的集合位于。中的繪圖函數(shù)在中,有行標簽列標簽分組信息。密度圖通過計算可能會產(chǎn)生觀測數(shù)據(jù)的連續(xù)概率分布的估計而產(chǎn)生的。在探索式數(shù)據(jù)分析工作中,同時觀察一組變量的散布圖是很有意義的。 我們在上一篇介紹了 pandas,本篇介紹 matplotlib。 繪圖和可視化 一個用于創(chuàng)建出版質量圖表的桌面繪圖包。 Matplotlib API入門 Figure ...
閱讀 2831·2021-09-28 09:45
閱讀 1506·2021-09-26 10:13
閱讀 897·2021-09-04 16:45
閱讀 3661·2021-08-18 10:21
閱讀 1083·2019-08-29 15:07
閱讀 2632·2019-08-29 14:10
閱讀 3146·2019-08-29 13:02
閱讀 2458·2019-08-29 12:31