SVG入门指南(5分钟)-假装画K线图!!!

734 阅读3分钟

SVG

1. 设置SVG

包裹并定义整个矢量图。<svg> 标签之于矢量图就如同 <html> 标签之于一个 web 页面。可设置宽高

设置了一个750*500的一个svg画布

<svg width="750" height="500">
</svg>

基础css

svg {
  stroke: #000; // 黑色
  stroke-width: 5; // 宽度5
  stroke-linecap: round; // 线条圆角
  stroke-linejoin: round; // 线条连接处圆角
  fill: none; // 图标是无填充的
}

2. line(直线)

4个属性:

起点(x坐标,y坐标)

终点(x坐标,y坐标)

以svg画布左上角坐标(0,0)为坐标圆点

画了一条250的直线

<svg width="750" height="500">
    <line x1="50" y1="50" x2="300" y2="50"></line>
</svg>

图形如下:

image-20220609092941917.png

3. polyline(折线)

1个属性:

points两个数值表一个点,对应坐标轴(x,y),点和点之间的线段会自动绘制出来,依次类推

<svg width="750" height="500">
    <polyline points="60 60 100 105 60 150"></polyline>
</svg>

图形如下:

image-20220609092821300.png

4. rect矩形(闭合)

4个属性:

x,y代表左上角x,y轴的坐标值

width、height矩形的宽高

<svg width="750" height="500">
    <rect x="50" y="50" width="300" height="50"></rect>
</svg>

图形如下:

image-20220609093022821.png

5. 创建圆和椭圆(闭合)

4个属性:

cx、cy:中心位置在 x 、y轴上的坐标

rx、ry:沿 x、y 轴向的半径,也就是它会把图形分割成上下、左右两部分

<svg width="750" height="500">
    <ellipse cx="120" cy="120" rx="100" ry="100"></ellipse>
    <ellipse style="fill:black" cx="400" cy="120" rx="80" ry="20"></ellipse>
</svg>

图形如下

image-20220609093511254.png

6. polygon创建多边形(闭合)

1个属性: points两个数值表一个点,对应坐标轴(x,y),点和点之间的线段会自动绘制出来,依次类推

<polyline> 元素几乎一样,折线 <polyline> 不是闭合的,而多边形 <polygon> 是自动闭合

<svg width="750" height="500">
    <polygon points="60 60 100 105 60 150"></polygon>
</svg>

图形如下:

image-20220609094423923.png

7. path点和点之间的线来创建任意形状

1个属性,3个附属性

ddata,在这里,你将定义路径的所有点和线(M、L、Z在d里面)

M: 表示移动到(moveto)。它用 x 值和 y 值来给定一条新的路径的起始点(M表绝对坐标集合,m表相对坐标)

L :表示划线到(lineto)。从当前位置到新的位置画一条线(L 表绝对坐标集合,l表相对坐标集合)

Z :表示闭合路径。通过在当前点和路径的起始点之间画一条直线来闭合形状

<svg width="750" height="500">
    <path d="M 50 50 L 300 50 L 300 100 L 50 100 Z"></path>
</svg>

图形入下:

image-20220609095623059.png

8.defs

用作定义一个可复用的图形。初始情况下 <defs> 里面的内容是不可见的。即图标在我们明确地去使用它们之前默认都是隐藏的

<svg width="750" height="500">
    <defs>
        <ellipse cx="120" cy="120" rx="30" ry="30"></ellipse>
	<ellipse style="fill:black" cx="250" cy="120" rx="80" ry="20"></ellipse>
    </defs>
</svg>

图形如下:

image-20220609101537599.png

9.g创建组合对象

将多种形状组合起来。将组合后的形状置于 <defs> 中可以让它能够被复用

<svg width="750" height="500">
    <!-- <defs> -->
        <g id="line">
            <ellipse cx="120" cy="120" rx="30" ry="30"></ellipse>
            <ellipse style="fill:black" cx="250" cy="120" rx="80" ry="20"></ellipse>
	</g>
	<g id="unline">
            <polygon points="350 350 400 400 350 450"></polygon>
            <rect x="420" y="380" width="50" height="50"></rect>
	</g>
    <!-- </defs> -->
</svg>

图形如下:

image-20220609103921170.png

10.use

配合defs和g标签一起使用(获取在 <defs> 中定义的复用对象并在 SVG 中显示出来)

<svg width="750" height="500">
    <use href="#line"></use>
    <defs>
        <g id="line">
             <ellipse cx="120" cy="120" rx="30" ry="30"></ellipse>
             <ellipse style="fill:black" cx="250" cy="120" rx="80" ry="20"></ellipse>
        </g>
        <g id="unline">
            <polygon points="350 350 400 400 350 450"></polygon>
            <rect x="420" y="380" width="50" height="50"></rect>
        </g>
    </defs>
</svg>

图形如下:

image-20220609105425398.png

画一个非常有意思的图(微型K线走向)

html

<svg width="200" height="50">
    <polygon :fill="num < 0 ? 'url(#LinearGradien)' : 'url(#LinearGradien1)'" :points="klinegon('10, 20,18, 6, 20, 44, 12, 9,49, 20, 18, 6, 20, 0, 29, 34, 20, 0, 12, 9,10, 20, 18, 26')">
    </polygon>
    <polyline fill="none" :points="kline('10, 20,18, 6, 20, 44, 12, 9,49, 20, 18, 6, 20, 0, 29, 34, 20, 0, 12, 9,10, 20, 18, 26')" :stroke="num < 0 ? '#3AB293' : '#E5575A'" stroke-width="1" stroke-linecap="square" ref="btc">
    </polyline>
    <defs>
	<linearGradient id="LinearGradien">
            <stop offset="0" stop-color="rgba(58,178,147,0.4)" />
            <stop offset="1" stop-color="rgba(58,178,147,0)" />
	</linearGradient>
	<linearGradient id="LinearGradien1">
            <stop offset="0" stop-color="rgba(229,87,90,0.4)" />
            <stop offset="1" stop-color="rgba(229,87,90,0)" />
	</linearGradient>
    </defs>
</svg>

方法

//获取走势图,val是传过来的y坐标,因为x坐标可自行等间距取
// 走势图线
kline(val) {
	let valarr = val.split(",");
	let max = Math.max(...valarr);// 取y坐标最大值
	let min = Math.min(...valarr);// 取y坐标最小值
	let equal = (max - min) / 50;// 差值之间的等分(均分值)50是svg的高度
	let arr = [];
	for (let i = 0; i < valarr.length; i++) {
		let x = (200 / valarr.length) * i;// 获取等间距的坐标,从0开始(svg高度是200)
		let y = (max - valarr[i]) / equal;// 这里是以最大值做为基准参考,按比例计算出y轴坐标(以某个作为参考)
		arr.push(x);
		arr.push(y);
	}
	if (!isNaN(arr[0]) && !isNaN(arr[1])) {
		return arr.toString().replace(/,/g, " ").replace(/NaN/g, 0);// 返回与point需要的x,y格式进行绘图
	} else {
		return "0,0";//避免传入的非数字,画出的图有问题
	}
},
// 填充走势图区域
klinegon(val) {
	let valarr = val.split(",");
	let max = Math.max(...valarr);
	let min = Math.min(...valarr);
	let equal = (max - min) / 50;
	let arr = [];
	for (let i = 0; i < valarr.length; i++) {
		let x = (200 / valarr.length) * i;
		let y = (max - valarr[i]) / equal;
		arr.push(x);
		arr.push(y);
	}
	arr.unshift(50);
	arr.unshift(0);
	arr.push(200);
	arr.push(50);// 多加这两个值是为了能填充走势图线下区域(根据需求,你也改变着两个坐标,填充走势图上区域)
	return arr.toString().replace(/,/g, " ").replace(/NaN/g, 0);
}

图形如下:

image-20220609160128584.png