d3入门篇(四):绘制完全柱状图增加过渡结果

这篇进修笔记是入门篇的末了一部份,将前几篇的内容整合到一同,绘制带过渡效果的柱状图,此次先给人人看一下效果图。

效果

《d3入门篇(四):绘制完全柱状图增加过渡结果》

媒介

先放效果图是想反应一下在整合基础知识绘制完全柱状图碰到的几个题目:

  • 全部柱状图的规划,比方哪些元素包在一个<g>标签下,哪些元素是嵌套关联;
  • 假如不采纳translate,transform 翻转height属性的值,怎样让矩形一般方向显现;
  • 怎样绘制笔墨;
  • 怎样为柱状图增加过渡效果;
  • 坐标轴的位置怎样肯定,x轴怎样分别刻度,怎样让刻度显现在矩形的正下方;

!!!! 接下来将逐一处理上述涌现的题目!!!!

Problem1:柱状图的团体规划

Solution

(1)为了绘制时,图形周围留有空缺地区,我们起首设置一个padding值;
var padding={top:40,bottom:40,left:40,right:40};//定义距离
(2)我们斟酌在svg画布上举行绘制,采纳以下的构造举行画图:
    <svg>
        //将x轴包裹在一个g标签下
        <g></g>
        //将y轴包裹在一个g标签下
        <g></g>
        //将全部柱状图的矩形及笔墨包裹在一个g标签下
        <g>
            //将柱形图的每一个矩形与它响应的值包裹在一个g标签下
            <g>
                <rect>
                <text>
            </g>
        </g>
    </svg>

Problem2:怎样根据垂直向上的方向显现矩形

Solution
之前的几篇文章我都是经由过程transform变更完成了矩形的翻转,这篇文章引见一个新的思绪。
起首肯定一个矩形须要四要素(x,y,width,height),同时我们须要注重,画布的坐标轴方向为程度向右和垂直向下。height是我们数据可视化的展现部份,即数据的绑定部份,x,y肯定了绘制矩形的左上角坐标。
这里供应一个思绪:
假如根据一般垂直向下的方向绘制矩形时,请求矩形的bottom处在统一程度线上,y+height==牢固值;也就是数据(height)大的部份,我们愿望矩形的绘制肇端点(y)的值较小,数据小(height)的部份,我们愿望矩形的绘制肇端点(y)的值较大。
因而我们能够经由过程定义比例尺完成这个功用,将dataset中大的数值,映射出range中小的数值。

//定义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中已处理的规划计划题目,我们的要领是将矩形与笔墨包在一个g标签下,所以绘制笔墨与绘制矩形的要领雷同,在<g>标签下增加<text>标签,同时须要设定:
(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():设定元素从肇端状况到停止状况的过渡时刻;
  • .delay():设定元素实行过渡效果的时刻距离;
  • .ease():设定过渡的动画效果;

在为元素增加过渡效果时,初始状况,停止状况尤为重要,柱状图为例剖析一下元素的两个状况:

明白柱形图为每一个矩形增加过渡时,只要两个属性值须要转变,一个是y的值,一个是height的值;

肇端状况:柱状图的肇端状况非常好明白,就是矩形不显现的状况,即y值设定为前文提到的牢固值,height设定为0;
停止状况:柱状图的停止状况应该是矩形元素和笔墨都可视化牢固显现出来,即为一般绑定元素时设定的相干属性值。

//为矩形增加过渡效果
.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
在最先进修坐标轴的时刻,只完成了增加y轴,在此次完全柱状图完成中,尝试增加x轴却碰到了题目。在这个例子中我们一共绑定了8个数据,那末怎样让x轴的刻度匀称的显现在每一个矩形的下方呢?
在定义x轴的时刻我用了ScaleBand()这个要领:

//在range返回等差数列
var xScale=d3.scaleBand()
.domain(d3.range(dataset.length))
.rangeRound([0,dataset.length*(rectWidth+(rectPadding/2))]);
var xAxis=d3.axisBottom(xScale)
.ticks(5);

既然比例尺返回一个等差数列,所以我们请求在柱状图地区,每一个矩形和空缺距离这个团体是雷同的,所以我的完成是每一个矩形摆布各是半个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);
})

附录

接下来会写进阶篇的进修笔记

    原文作者:winteraq
    原文地址: https://segmentfault.com/a/1190000017416306
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞