1、项目需求
项目中写好车站及图元的绘制方法,按照要求动态生成车站成品图。车站成品图涉及图元较多,如果每次打开页面动态绘制会占用较长时间,影响加载效率和用户体验。
2、解决方案
决定采用动态引入成品SVG图的方法。首先,使用绘制方法,生成车站svg代码,然后将浏览器中的svg代码复制粘贴出来,作为静态svg文件引入。
3、具体实现步骤
(1) vue中引入svg-sprite-loader,在vue.config.js中配置svg读取路径。
chainWebpack(config) {
config.module
.rule('icons')
.test(/\.svg$/)
.include.add([resolve('src/icons'), resolve('src/assets/jgsvg')])
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
(2) 将成品车站图从浏览器控制台中复制出来,在网站中进行格式化,并查看格式化后的svg图形是否可以正常展示。
这里推荐两个网站:
将车站成品图代码放到src/assets/jgsvg目录下。
具体格式化后代码见下图。

(3) 引入方法,使用import引入svg文件
html:
<div class="editContainer_SVG"></div>
js:
import zhanchang from "@/assets/jgsvg/chang.svg"
// 引入站场图
importStation() {
// 引入svg
let zhanchangSvg = zhanchang.content.replace(new RegExp("symbol", "gm"), "svg");
let str = "width='100%' height='100%' ";
// 添加svg属性
let svgText = insertStr(zhanchangSvg, 5, str);
$(".editContainer_SVG").append(svgText);
this.$nextTick(() => {
// 添加属性
let self = this;
// 这里必须指定已存在的元素 .editContainer_SVG
const pageSvg = d3.select(".editContainer_SVG #icon-TSRSzhanchang");
this.pageSvg = pageSvg;
let g =d3.select(".editContainer_SVG #icon-TSRSzhanchang >g");
this.pageG = g;
// 设置滚动及缩放限制
this.svgZoom = d3.zoom()
.scaleExtent(this.svgScaleExtent) // 添加放大限制
.on("zoom", zoomed);
this.pageSvg.call(this.svgZoom)
.on("wheel", function () {
d3.event.preventDefault(); // 放大倍数达到上下限时svg图形不随鼠标滚动上下移动
})
.on("dblclick.zoom", null)
// 获取全体包,刷新全体包状态
let allPakcData = this.$store.getters.packData;
this.renderDom(allPakcData);
// zoom 滚动及缩放方法
function zoomed() {
let transforms = d3.event.transform;
self.svgZoomTransform = transforms;
// // // $(".rectTipView").empty();
self.rectTipFlag = false;
self.pageG.attr("transform", transforms);
}
})
}
/**
* 在指定位置插入字符串
* @param {*} soure
* @param {*} start
* @param {*} newStr
*/
export function insertStr(soure, start, newStr) {
return soure.slice(0, start) + newStr + soure.slice(start)
}
.editContainer_SVG所在的div为svg的容器。
使用import引入svg静态文件后,会改变svg原有的代码,
(1) 由symbol 标签包裹,需要替换symbol为svg;
(2) width,height属性消失,需要动态拼接width、height属性
(3) id会有所调整,编程icon_文件名,这里的需要对接下来代码中的指定元素进行修改。
(4) d3.select(".editContainer_SVG #icon-TSRSzhanchang") 这里一定要加原dom中已存在的元素 .editContainer_SVG,否则接下来设置的svg拖动、缩放无效。