D3-1

简介

D3(Data Driven Documents),数据驱动文档。

在Vue中使用

安装

npm install d3 --save

引用

在组件中引用

import * as d3 from 'd3'

使用D3操作SVG

SVG

SVG(Scalable Vector Graphics),可缩放矢量图形,使用XML格式定义图像。即两点之间的连线是直线的话,不论怎样放大直线,两点之间的连线永远是直线,即放大不会失真,具有画图细腻性的特点。

在html中使用svg

<svg></svg>

SVG常见属性

  • id,class 特殊的属性,可以使用.attr设置
  • x , y , cx , cy 屏幕坐标系,cx,cy表示圆心的坐标
  • fill , stroke
  • height , width, r 圆的半径
  • transform -> translate, rotate, scale 平移/旋转/缩放

SVG属性非常多,且属性的取值范围和类型各不同,养成及时查阅的习惯非常重要

设置属性

设置/获取元素属性

element.attr('attr_name','attr_value')  //设置属性
var value = element.attr('attr_name')  //获取属性

使用D3添加或删除SVG元素

链式添加

const myRect = d3.select('#mainsvg').append('g').attr('id','maingroup').attr('height','100px')   //设置id后继续设置高度

屏幕空间坐标系

屏幕空间的坐标系与常见的坐标系不用,屏幕坐标系具有以下特点(图二):

  • 左上方为远点
  • X、Y分别为水平向右、垂直向下

比例尺

  • 比例尺用于把实际的数据空间映射到屏幕空间(一个像素对应多少数据)
  • 比例尺非常重要,会经常同时传给坐标轴与数据
const mySale = d3.scaleLinear() //定义比例尺,返回值本质上是函数
const mySale = d3.scaleLinear().domain([0,10]).range([-10001000]) //配置比例尺,domain表示实际数据,range表示屏幕空间,上述语句表示将0-10的数据映射到屏幕-1000-1000的范围
mySale(5); //结果为0,5为0-10的中点,输出为-1000-1000的中点

使用D3生成柱状图

定义Margin

  • SVG对于D3.js来说是一个画布
  • SVG范围外的任何内容属于画布之外,浏览器不予显示
  • D3只对上图Margin的区域进行操作,防止D3坐标轴画到屏幕外边
const margin = {top:60,right:30,bottom:60,left:50}; //定义margin ,数据可自定义

vue

<template>

<svg width="1400" height="800" id="id" class="svgs"></svg>
</template>

<script>
import * as d3 from 'd3'
export default{
    data(){
        return{
            dataList:[
                {name:'zby',value:12},
                {name:'as',value:2},
                {name:'asd',value:20},
                {name:'gtr',value:17},
                {name:'fgb',value:12},
                {name:'ehr',value:19},
                {name:'dsj',value:9},

            ]
        }
    },
    mounted() {
        this.showSvg();
    },
    methods:{
        showSvg(){
            const svg = d3.select('#id'); //使用id获取svg画布
            const width = +svg.attr('width'); //+将字符串转为数字
            const height = +svg.attr('height');
            const margin = {top:100,right:30,bottom:60,left:150};
            const innerWidth = width-margin.left-margin.right;
            const innerHeight = height - margin.top - margin.bottom;

            //定义比例尺
            //x轴比例尺
            const xScale = d3.scaleLinear()
            //d3.max第一个参数指明操作对象,第二个参数值的意思是this.dataList['value'],然后取value最大值
            .domain([0,d3.max(this.dataList, d=>d.value)])  //取决于渲染的值,此处取决于dataList
            .range([0,innerWidth]);
            //y轴比例尺
            const yScale = d3.scaleBand()
            .domain(this.dataList.map(d=>d.name))  //映射this.dataList['name']
            .range([0,innerHeight])
            .padding(0.1); //在y轴的每个变量中间预留位置

            //定义中间位置
            const g = svg.append('g').attr('id','maingroup')
            .attr('transform', `translate(${margin.left},${margin.top})`);//将坐标轴移到margin左上角

            //生成坐标轴
            //定义y轴
            const yAxis = d3.axisLeft(yScale);
            g.append('g').call(yAxis); //把坐标轴容器填满,.call才是真正把坐标轴渲染出来的方法
            //定义x轴
            const xAxis = d3.axisBottom(xScale);
//            g.append('g').call(xAxis);//x轴在上方
            g.append('g').call(xAxis).attr('transform',`translate(0,${innerHeight})`); //将x轴平移到下方

            //画柱状图
            this.dataList.forEach(d=>{
                g.append('rect')
                .attr('width',xScale(d.value))  //以value的值渲染柱形图width
                .attr('height',yScale.bandwidth())  //y轴默认宽度
                .attr('fill','green')  //柱形图颜色
                .attr('y',yScale(d.name)) //柱形在y轴的渲染位置
            })
        }
    }
}    
</script>

<style>
</style>

Data-Join

Data-Join 本质上是将数据与图元进行绑定

  • 每个国家的人数绑定到矩形的长度
  • 疫情感染的人数绑定到圆的半径

使用Data-Join可以省去大量根据数据设置图元属性的代码量,对于动态变化的数据提供统一的接口

  • 以数据为中心的可视化操作(根据数据的每个属性自动调整绑定图元的属性)
  • 不再需要手动添加、修改、删除图元(会根据Data-Join的绑定自动推断)
  • 如果图元的数目不等于数据的条目(根据数据条目的数量选定相应数量的图元)

D3.js绑定数据的三个状态

  • Update 图元与数据条目相同,上述均为单纯的update
  • Enter 数据的条目多于图元甚至没有图元,常用于第一次绑定数据
  • Exit 数据的条目少于图元甚至没有数据,常用于结束可视化

使用Enter实现柱状图

画柱状图部分的代码改为列下的代码

//enter前的语句用于占位,enter后d3由enter进入update状态,当dataList不为空时将自动渲染,data用于绑定渲染的数据对象
g.selectAll('.dataRect').data(this.dataList).enter().append('rect')
            .attr('class','dataRect')
            .attr('width',d=>xScale(d.value))
            .attr('height',yScale.bandwidth())
            .attr('y',d=>yScale(d.name))
            .attr('fill','green')
            .attr('opacity',0.8)

CSV数据

常见的CSV文件数据格式为

  • 第一行是属性列表
  • 后续每行对应一条数据
  • CSV本质上是纯文本,区别于EXCEL格式

D3读取CSV数据

d3.csv('path/to/data.csv').then(data =>{})
  • .csv函数 的返回值是一个JS的Promise对象(Promise对象用于执行异步操作)
  • .then() 的参数为一个函数 ,参数为.csv的返回值
  • d3.csv() 会正常向服务器请求数据,在请求并处理好之后,将结果扔给.then()中的回调函数。
d3.csv('path/to/data.csv').then(data=>{
    data = data.filter(d=>d['地区'] !== '总计');  //保留地区不是总计的数据
    data.forEach(d=>{
        name = d['name']  //获取name属性
    })
})

Path

path 元素是SVG基本形状中最强大的一个。可以用path绘制基本图形,包括贝塞尔曲线、2次曲线等

  • path元素的形状是通过属性d来定义的,属性d的值是一个“命令+参数”的序列

path属性

  • d

  • fill 填充颜色

  • stroke 描边颜色

  • stroke-width 描边宽度


   转载规则


《D3-1》 fightingtree 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录