一、数据可视化设计
嵌套模型(Nested Model)
Domain: 目标用户
Abstration: what展示什么,why用户的要求
idiom: how怎么展示
数据集类型 Dataset Types
数据类型 Data Types
Item, link, attribute, position, grid
属性类型 Attribute Types
Data Abstraction
任务模式Task Abstraction
数据结构 Idiom Structure
- Marks (items,links)
- Channels (attributes): change appearance of marks based on attributes
Marks for items:
Marks for links:
Channels:
Expressiveness of Channels:
Channel Effectiveness
Accuracy, Discriminability, Separability, popup
Color颜色设计
- Color palette:univariate, bivariate 色盘
- Color deficiency:red&green,blue&yellow,white&black
- Color space:RGB,HSV
- Color contrast & naming
数据交互Interaction
关系网络
1. node-link
2. Adjacency matrix 邻接矩阵
邻接矩阵和node-link比较:
3. Tree 树
二、SVG可缩放矢量图形(Scalable Vector Graphics)
svg可以直接嵌套html中
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
</svg>
Ⅰ.形状 Shapes
- 矩形 <rect>
- 圆形 <circle>
- 椭圆 <ellipse>
- 线 <line>
- 折线 <polyline>
- 多边形 <polygon>
- 路径 <path>
<!--矩形 rxry圆角-->
<rect x="50" y="20" rx="20" ry="20" width="150" height="150" style="fill:red;stroke:black;stroke-width:5;opacity:0.5"/>
<!--圆形-->
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
<!--椭圆-->
<ellipse cx="300" cy="80" rx="100" ry="50" style="fill:yellow;stroke:purple;stroke-width:2"/>
<!--直线-->
<line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2"/>
<!--多边形 points对应每个顶点-->
<polygon points="200,10 250,190 160,210" style="fill:lime;stroke:purple;stroke-width:1"/>
<!--多线段-->
<polyline points="20,20 40,25 60,40 80,120 120,140 200,180" style="fill:none;stroke:black;stroke-width:3" />
<!--路径-->
<path d="M150 0 L75 200 L225 200 Z" />
Ⅱ. Text文本
<text x="0" y="15" fill="red" transform="rotate(30 20,40)">I love SVG</text>
Ⅲ. Stroke 属性
- stroke:定义一条线,文本或元素轮廓颜色
- stroke-width:定义了一条线,文本或元素轮廓厚度
- stroke-linecap:定义不同类型的开放路径的终结 butt,round,square
- stroke-dasharray:用于创建虚线
<path stroke="red" d="M5 20 l215 0" />
<path stroke-width="2" d="M5 20 l215 0" />
<path stroke-linecap="butt" d="M5 20 l215 0" />
<path stroke-dasharray="20,10,5,5,5,10" d="M5 60 l215 0" />
Ⅳ.其他css属性
Transform: translate, scale, rotate 2d转换,缩放,旋转
三、d3.js
使用Web标准做数据可视化的JavaScript库。 D3帮助我们使用SVG, Canvas 和 HTML技术让数据生动有趣。 D3将强大的可视化,动态交互和数据驱动的DOM操作方法完美结合,让我们可以充分发挥现代浏览器的功能,自由的设计正确的可视化界面。
svg与canvas
svg是及其形状都是标签形式的,就像提供了很多各种形状,你选择图形给上贴。而且每个形状都支持事件以及属性。
canvas是给你一个画板,给你一个笔,调api绘制来绘制图形。
svg可以很轻松的捕捉鼠标事件,比如鼠标移入到矩形等等。也可以直接操作某个形状的属性。
canvas只能先捕获事件,然后定位,计算是否在某个形状上。绘制大数据量时,性能比较好。
d3和echarts
echart是配置式的,需要按照文档进行配置即可。
d3是需要通过调用api,先处理数据转换。绘制,加入交互。
所以目前推荐在常规交互下的图表使用echarts,定制度较高或者重交互的图表可以使用d3js使用svg绘制。
官方使用文档
API文档:d3/API.md at main · d3/d3 · GitHub
代码
- D3 Query
var body = d3.select("body"); //选择文档中的body元素
var p1 = body.select("p"); //选择body中的第一个p元素
var p = body.selectAll("p"); //选择body中的所有p元素
var id = body.select("#id"); //选择body中id元素
var class = body.select(".class");//选择body中class类元素
- D3 Scales 比例尺
var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];
var min = d3.min(dataset);
var max = d3.max(dataset);
var linear = d3.scale.linear()
.domain([min, max])
.range([0, 300]);
linear(0.9); //返回 0
linear(2.3); //返回 175
linear(3.3); //返回 300
- D3 Axes 坐标轴
//定义坐标轴
var axis = d3.svg.axis() //坐标轴组件
.scale(linear) //指定比例尺
.orient("bottom") //指定刻度的方向
.ticks(7); //指定刻度的数量
//在 SVG 中添加坐标轴
svg.append("g").call(axis);
- Margin
const margin = {top:60, bottom:60, left:200, right:30};
//append group
const g = svg.append('g').attr('id','maingroup')
.attr('transform',`translate(${margin.left},${margin.top})`);
- Data Binding (enter,update,remove) 数据绑定
- update()
当对应的元素正好满足时 ( 绑定数据数量 = 对应元素 ),实际上并不存在这样一个函数,只是为了要与之后的 enter 和 exit 一起说明才想象有这样一个函数。但对应元素正好满足时,直接操作即可,后面直接跟 text ,style 等操作即可。
- enter()
当对应的元素不足时 ( 绑定数据数量 > 对应元素 ),当对应的元素不足时,通常要添加元素,使之与绑定数据的数量相等。后面通常先跟 append 操作。
- exit()
当对应的元素过多时 ( 绑定数据数量 < 对应元素 ),当对应的元素过多时,通常要删除元素,使之与绑定数据的数量相等。后面通常要跟 remove 操作。
- bar chart柱状图
g.selectAll(".bar").data(data).enter()
.append("rect")
.attr("class","bar")
.attr("x",0)
.attr("y", d => yScale(d.name))
.attr("width", d => xScale(d.value))
.attr("height", d=>yScale.bandwidth())
.attr("fill","steelblue");
- Data Loading数据加载
- Color
d3.rgb()
d3.scaleOrdinal()
- transition 动画
- 交互事件
var circle = svg.append("circle");
circle.on("click", function(){
//在这里添加交互内容
});
var rects = svg.selectAll(".MyRect")
.data(dataset)
.enter()
.append("rect")
.attr("class","MyRect") //把类里的 fill 属性清空
.attr("fill","steelblue") //填充颜色不要写在CSS里
.on("mouseover",function(d,i){
d3.select(this)
.attr("fill","yellow");
})
.on("mouseout",function(d,i){
d3.select(this)
.transition()
.duration(500)
.attr("fill","steelblue");
});
//或者用d3-tips
const tip= d3.tip()
.attr("class","d3-tip")
.html(function(d){
return d.value;
})
svg.call(tip);
selection.on("click", function(d){
tip.show(d);
tip.hide(d);
});
d3-tip写tooltip: 使用 d3-tip 向 d3 条形图添加工具提示_allway2的博客-CSDN博客_d3 tips
总结通用架子
我们可以看到,d3js做图表比较麻烦,所有的内容基本需要自己调用api绘制,正是这样可控性高,可以很轻松的实现各种图表定制。
d3实现一个交互图表。我们其实都是需要这三步:
第一步,初始化,与数据发生变化无关的相关参数,dom及对象
第二步,绘制函数,将数据进行绑定,绘制出与数据相关的形状及对象。
第三步,加入交互,各种交互事件,定时更新等等。
常见图表的绘制
柱状图,折线,散点图:直接使用比例尺,即可换算位置和大小。
d3-chord:制作玄图
d3.pie:制作饼图,环图,仪表盘
d3-geo:制作地图
d3-force:力导图
d3-hierarchy:树图,树矩形图,包等等
d3.histogram:直方图
交互类:
d3-zoom:实现缩放
d3-drag:实现拖动
案例&模板
问题汇总
- d3.format可用类型,以及SI前缀?
exponent (e),geneal(g),fixed(f),integer(d),round(r),%,SI前缀(s)
- d3.csv等文件读取时是异步操作要注意