数据可视化-基础知识

2020/10/18 数据可视化
// 数据可视化
1. 数据可视化简单理解,就是将数据转换成易于人员辨识和理解的视觉表现形式
   如各种 2D 图表、3D 图表、地图、矢量图等等,随着技术的不断进步,数据可视化的边界也在不断扩大
2. 数据可视化起源于 20 世纪 60 年代诞生的计算机图形学 // 简称 CG
----------------------------------------------------------------------------------------------
// 数据可视化解决方案
1. 最底层:
    Skia // Skia是 Chrome 和 Android 的底层 2D 绘图引擎
    OpenGL // OpenGL(Open Graphics Library)是2D、3D图形渲染库,它可以绘制从简单的2D图形到复杂的3D景象
2. 浏览器层:
    Chrome:使用 Skia 作为绘图引擎,向上层开放了 canvas、svg、WebGL、HTML 等绘图能力
3. 应用层:
    three.js // 3D绘图
    zrender // canvas的封装
    d3 // 矢量图绘制
4. 框架层:
    Highcharts、ECharts、AntV
----------------------------------------------------------------------------------------------
// canvas
// 通过 canvas API
1. 编写 canvas 标签(注意指定宽高)
2. 获取 canvas DOM 对象
3. 获取 Canvas 对象
4. 设置绘图属性
5. 调用绘图 API
<canvas id="canvas" width="800" height="800"></canvas>
const canvas = document.getElementById('canvas'); // 获取 DOM 对象
const ctx = canvas.getContext('2d'); // 获取 Canvas 对象
ctx.fillStyle = 'red'; // 填充为红色
ctx.fillRect(0, 0, 50, 50); // 绘制矩形

ctx.beginPath(); // 开始绘制路径
ctx.lineWidth = 1; // 线条宽度
ctx.strokeStyle = 'blue'; // 线条填充色
ctx.moveTo(100, 100); // 起点坐标
ctx.lineTo(250, 75); // 中间点坐标
ctx.lineTo(300, 100); // 终点坐标
ctx.stroke(); // 绘制线段

ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'green'; // 圆形边框色
ctx.fillStyle = 'red'; // 圆形填充色
ctx.arc(200, 200, 50, 0, 2 * Math.PI); // 绘制圆形
ctx.stroke(); // 绘制圆形的边框
ctx.fill(); // 绘制圆形的填充色

ctx.beginPath();
ctx.lineWidth = 1;
ctx.strokeStyle = 'red';
ctx.moveTo(300, 300);
ctx.lineTo(301, 301); // 绘制一个点
ctx.stroke();
----------------------------------------------------------------------------------------------
// SVG是一种基于 XML 的图像文件格式,它的英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形
// 通过 html 标签
1. 编写 svg 标签,指定宽高
2. 编写 svg 绘图标签
3. 编写绘图属性和样式
<svg width="800" height="800">
    <rect
    width="50"
    height="50"
    style="fill:red;stroke-width:0;stroke:rgb(0,0,0);"
    />
    <line
    x1="100"
    y1="100"
    x2="250"
    y2="75"
    style="stroke:blue;stroke-width:1"
    />
    <line
    x1="250"
    y1="75"
    x2="300"
    y2="100"
    style="stroke:blue;stroke-width:1"
    />
    <circle
    cx="200"
    cy="200"
    r="50"
    stroke="green"
    stroke-width="2"
    fill="red"
    />
    <line
    x1="300"
    y1="300"
    x2="301"
    y2="301"
    style="stroke:red;stroke-width:1"
    />
</svg>
----------------------------------------------------------------------------------------------
// zrender是二维绘图引擎,它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器
// 基于 canvas
1. 引入 zrender 库
2. 编写 div 容器
3. 初始化 zrender 对象
4. 初始化 zrender 绘图对象
5. 调用 zrender add 方法绘图
<div id="container" style="width: 800px;height: 800px;"></div>
<script src="https://cdn.jsdelivr.net/npm/zrender@4.3.0/dist/zrender.js"></script>
var zr = zrender.init(document.getElementById('container'));
var rect = new zrender.Rect({
shape: {
    x: 0,
    y: 0,
    width: 50,
    height: 50
},
style: {
    fill: 'red',
    lineWidth: 0
}
});
var line = new zrender.Polyline({
shape: {
    points:[
    [100, 100],
    [250, 75],
    [300, 100]
    ]
},
style: {
    stroke: 'blue',
    lineWidth: 1
}
});
var circle = new zrender.Circle({
shape: {
    cx: 200,
    cy: 200,
    r: 50
},
style: {
    fill: 'red',
    stroke: 'green',
    lineWidth: 2
}
});
var point = new zrender.Polyline({
shape: {
    points:[
    [300, 300],
    [301, 301]
    ]
},
style: {
    stroke: 'red',
    lineWidth: 1
}
});
zr.add(rect);
zr.add(line);
zr.add(circle);
zr.add(point);
----------------------------------------------------------------------------------------------
// D3(Data-Driven Documents) 是一个 Javascript 图形库,基于 Canvas、Svg 和 HTML
<p>Vue</p>
<p>React</p>
<p>Agular</p>
<button id="datum">datum</button>
<button id="data">data</button>
<script src="https://d3js.org/d3.v5.js"></script>
var body = d3.select("body");
var p = body.selectAll("p");
function doDatum() {
// datum
var str = "Framework";
p.datum(str);
p.text(function(d, i) {
    return `${d}-${i}`;
});
}
function doData() {
// data
var dataset = ['Vue', 'React', 'Agular'];
p.data(dataset)
    .text(function(d, i) {
    return `${d}-${i}`;
    });
}
document.getElementById('datum').addEventListener('click', function(e) {
    doDatum();
});
document.getElementById('data').addEventListener('click', function(e) {
    doData();
});
----------------------------------------------------------------------------------------------
// WebGL(Web Graphics Library)是一种 3D 绘图协议,WebGL可以为 HTML5 Canvas 提供硬件3D加速渲染
// 这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示 3D 场景和模型了,还能创建复杂的导航和数据视觉化
<canvas id="canvas" width="200px" height="200px"></canvas>
window.onload = function () {
    //顶点着色器程序
    var VSHADER_SOURCE =
        "void main() {" +
            //设置坐标
        "gl_Position = vec4(0.0, 0.0, 0.0, 1.0); " +
            //设置尺寸
        "gl_PointSize = 10.0; " +
        "} ";

    //片元着色器
    var FSHADER_SOURCE =
        "void main() {" +
            //设置颜色
        "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" +
        "}";
    //获取canvas元素
    var canvas = document.getElementById('canvas');
    //获取绘制二维上下文
    var gl = canvas.getContext('webgl');
    if (!gl) {
        console.log("Failed");
        return;
    }
    //编译着色器
    var vertShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertShader, VSHADER_SOURCE);
    gl.compileShader(vertShader);

    var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragShader, FSHADER_SOURCE);
    gl.compileShader(fragShader);
    //合并程序
    var shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertShader);
    gl.attachShader(shaderProgram, fragShader);
    gl.linkProgram(shaderProgram);
    gl.useProgram(shaderProgram);

    //绘制一个点
    gl.drawArrays(gl.POINTS, 0, 1);
}
----------------------------------------------------------------------------------------------
// Three.js是一个基于 WebGL 的 Javascript 3D 图形库
<script src="https://cdn.jsdelivr.net/npm/three@0.116.1/build/three.js"></script>
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.z = 1;
    scene = new THREE.Scene();
    geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
    material = new THREE.MeshNormalMaterial();
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );
}
function animate() {
    requestAnimationFrame( animate );
    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;
    renderer.render( scene, camera );
}
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
Last Updated: 2024/6/11 14:20:38
    飘向北方
    那吾克热-NW,尤长靖