1.关于SVG
SVG全称为Scalable Vector Graphics,即可缩放矢量图形。它是一种使用XML表示的2D图形格式,可以为Web页面添加动态、交互式、可缩放的图形。相比于传统的栅格图像格式,SVG图像可以在任意大小的容器中无失真地缩放、旋转、裁剪;并支持分层、样式表定义、事件处理等复杂的图像处理操作。基于以上特性,SVG在Web开发中得到了广泛的应用。
由于SVG图像是基于文本的,因此可以直接在HTML代码中嵌入SVG图像。HTML使用<svg>标签进行SVG图像的嵌入,同时可以使用CSS和JavaScript处理及修改SVG图像。
2.SVG实现步进函数
2.1 生成折线图
首先,我们需要准备一组数据,这里以简单的五个点的数据为例:
<svg width="500" height="500">
<polyline points="50,400 100,250 180,300 300,200 350,250"
fill="none" stroke="black" stroke-width="2"/>
</svg>
其中,<polyline>标签用于绘制线条。points属性指定点的坐标,每个坐标用空格或逗号隔开。fill属性为填充颜色,none表示不填充。stroke属性为线条颜色,stroke-width属性为线条粗细。
2.2 添加坐标轴
接下来,我们需要给这个图形添加坐标轴。坐标轴分为水平坐标轴和垂直坐标轴,分别对应x轴和y轴。
<svg width="500" height="500">
<g transform="translate(50,450)">
<line x1="0" y1="0" x2="400" y2="0" stroke="black" stroke-width="2"/>
<polyline points="-5,-5 0,0 0,-10 5,-5"
fill="none" stroke="black" stroke-width="2"
transform="translate(400,0)"/>
<text x="0" y="20">0</text>
<text x="100" y="20">1</text>
<text x="200" y="20">2</text>
<text x="300" y="20">3</text>
<text x="400" y="20">4</text>
</g>
<g transform="translate(50,50)">
<line x1="0" y1="0" x2="0" y2="400" stroke="black" stroke-width="2"/>
<polyline points="-5,-5 0,0 0,5 5,0"
fill="none" stroke="black" stroke-width="2"
transform="translate(0,0)"/>
<text x="-20" y="5">400</text>
<text x="-20" y="75">350</text>
<text x="-20" y="145">300</text>
<text x="-20" y="215">250</text>
<text x="-20" y="285">200</text>
<text x="-20" y="355">150</text>
</g>
<polyline points="50,400 100,250 180,300 300,200 350,250"
fill="none" stroke="black" stroke-width="2"/>
</svg>
这里使用了<line>标签绘制直线,使用<polyline>标签绘制三角形,使用<text>标签绘制坐标轴上的数字。
2.3 数据与坐标的映射
上面的折线图只是静态的展示了一组数据,接下来,我们需要将数据与坐标进行映射,以便通过数据更新折线图。
<svg width="500" height="500">
<g transform="translate(50,450)">
<line x1="0" y1="0" x2="400" y2="0" stroke="black" stroke-width="2"/>
<polyline points="-5,-5 0,0 0,-10 5,-5"
fill="none" stroke="black" stroke-width="2"
transform="translate(400,0)"/>
<text x="0" y="20">0</text>
<text x="100" y="20">1</text>
<text x="200" y="20">2</text>
<text x="300" y="20">3</text>
<text x="400" y="20">4</text>
</g>
<g transform="translate(50,50)">
<line x1="0" y1="0" x2="0" y2="400" stroke="black" stroke-width="2"/>
<polyline points="-5,-5 0,0 0,5 5,0"
fill="none" stroke="black" stroke-width="2"
transform="translate(0,0)"/>
<text x="-20" y="5">400</text>
<text x="-20" y="75">350</text>
<text x="-20" y="145">300</text>
<text x="-20" y="215">250</text>
<text x="-20" y="285">200</text>
<text x="-20" y="355">150</text>
</g>
<polyline points="0,400 100,250 180,300 300,200 400,250"
fill="none" stroke="black" stroke-width="2"/>
</svg>
这里将折线图中x轴上的坐标从50、100、180、300、350映射为0、100、200、300、400;y轴上的坐标依次为400、250、300、200、250。
3.使用JavaScript动态更新数据并绘制折线图
3.1 HTML文件
首先,在HTML文件中添加一个按钮和一个折线图,代码如下:
<!--index.html-->
<html>
<head>
<meta charset="UTF-8">
<title>Line Chart</title>
<style>
button {
margin-top: 20px;
}
</style>
</head>
<body>
<svg id="line-chart" width="500" height="500">
<g transform="translate(50,450)">
<line x1="0" y1="0" x2="400" y2="0" stroke="black" stroke-width="2"/>
<polyline points="-5,-5 0,0 0,-10 5,-5"
fill="none" stroke="black" stroke-width="2"
transform="translate(400,0)"/>
<text x="0" y="20">0</text>
<text x="100" y="20">1</text>
<text x="200" y="20">2</text>
<text x="300" y="20">3</text>
<text x="400" y="20">4</text>
</g>
<g transform="translate(50,50)">
<line x1="0" y1="0" x2="0" y2="400" stroke="black" stroke-width="2"/>
<polyline points="-5,-5 0,0 0,5 5,0"
fill="none" stroke="black" stroke-width="2"
transform="translate(0,0)"/>
<text x="-20" y="5">400</text>
<text x="-20" y="75">350</text>
<text x="-20" y="145">300</text>
<text x="-20" y="215">250</text>
<text x="-20" y="285">200</text>
<text x="-20" y="355">150</text>
</g>
<polyline id="line" points="0,400 100,250 180,300 300,200 400,250"
fill="none" stroke="black" stroke-width="2"/>
</svg>
<button id="update">Update</button>
<script src="app.js"></script>
</body>
</html>
3.2 JavaScript文件
然后,在JavaScript文件的主函数中,获取按钮和折线图,给按钮绑定事件,在按钮点击时更新折线图的路径数据。
<!--app.js-->
'use strict';
var line = document.getElementById('line');
var updateBtn = document.getElementById('update');
var points = [
[0, 400],
[100, 250],
[180, 300],
[300, 200],
[400, 250]
];
updateBtn.addEventListener('click', function() {
for (var i = 0, len = points.length; i < len; i++) {
points[i][1] = Math.round(Math.random() * 400);
}
var path = 'M 0 ' + points[0][1];
for (var i = 1, len = points.length; i < len; i++) {
path += ' L ' + (i * 100) + ' ' + points[i][1];
}
line.setAttribute('d', path);
});
3.3 运行效果
最后,我们可以点击按钮,观察折线图的更新效果。
4.SVG实现走势图
基于以上的技术,我们可以实现一个简单的走势图。对于走势图,我们需要以下的步骤:
4.1 准备数据
这里我们使用了一组随机数据,共10组,每组数据表示当天的收盘价,数据格式为[日期, 收盘价],日期格式为'YYYY-MM-DD'。
<!--data.js-->
var data = [
['2019-01-01', 34845],
['2019-01-02', 34585],
['2019-01-03', 34443],
['2019-01-04', 34750],
['2019-01-05', 34960],
['2019-01-06', 35075],
['2019-01-07', 35232],
['2019-01-08', 35200],
['2019-01-09', 35216],
['2019-01-10', 35100]
];
4.2 绘制坐标轴和网格线
对于走势图,我们需要绘制x轴、y轴和网格线。具体实现如下:
<svg id="line-chart" width="800" height="600">
<g transform="translate(80,520)">
<line x1="0" y1="0" x2="600" y2="0" stroke="black" stroke-width="2"/>
<polyline points="-5,-5 0,0 0,-10 5,-5"
fill="none" stroke="black" stroke-width="2"
transform="translate(600,0)"/>
<text x="-10" y="20">0</text>
<text x="100" y="20">1月</text>
<text x="200" y="20">2月</text>
<text x="300" y="20">3月</text>
<text x="400" y="20">4月</text>
<text x="500" y="20">5月</text>
<text x="600" y="20">6月</text>
</g>
<g transform="translate(80,20)">
<line x1="0" y1="0" x2="0" y2="480" stroke="black" stroke-width="2"/>
<polyline points="-5,-5 0,0 0,5 5,0"
fill="none" stroke="black" stroke-width="2"
transform="translate(0,480)"/>
<text x="-10" y="5">35000</text>
<text x="-10" y="105">35500</text>
<text x="-10" y="205">36000</text>
<text x="-10" y="305">36500</text>
<text x="-10" y="405">37000</text>
</g>
<g transform="translate(80,20)">
<line x1="0" y1="0" x2="600" y2="0" stroke="#ccc" stroke-width="1" stroke-dasharray="5,5"/>
<line x1="0" y1="100" x2="600" y2="100" stroke="#ccc" stroke-width="1" stroke-dasharray="5,5"/>
<line x1="0" y1="200" x2="600" y2="200" stroke="#ccc" stroke-width="1" stroke-dasharray="5,5"/>
<line x1="0" y1="300" x2="600" y2="300" stroke="#ccc" stroke-width="1" stroke-dasharray="5,5"/>
<line x1="0" y1="400" x2="600" y2="400" stroke="#ccc" stroke-width="1" stroke-dasharray="5,5"/>
</g>
</svg>