vue中,js获取svg内容并填充到svg图中
js获取svg内容并填充到svg图中
最近遇到一个需求,要求前端通过接口获取svg中的内容,并且填充到svg图中,接下来我就记录一下整个实现过程。
- 第一步,找到svg图中每一个需要填充的数据的key值,把所有key值交给后端,后端会根据key值把value返回给前端,如下代码中
<g id="Value11" fill="#00FF00" stroke="none" font-family="Arial" font-size="29.9999988079072" PB:DisplayPointName="9" PB:DisplayTimeStamp="9" PB:HorzAlign="0" PB:ShowUOM="False" PB:IsMultiState="False" PB:NumberFormat="0.00" PBD:PtTagName="\\10.37.169.174\tags.DT_BB02_sab10a0101r" PB:PersistString="" PB:PtTagStatus="0" PB:PtTagTime="1970/1/1 8:00:00" PB:PtTagValue="No Data" PB:Type="7" PB:Visible="True" PB:Scripting="True">
<rect id="Value11_pbTextBoundingRectEl" x="4387" y="782" width="142" height="40" fill="none" stroke-width="0">
</rect>
<text id="Value11_pbTextEl" x="4458" y="812" fill="#00FF00" stroke="none" font-family="Arial" font-size="29.9999988079072" text-anchor="middle" PBD:Property="value">No Data</text>
</g>
PBD:PtTagName=“\10.37.169.174\tags.DT_BB02_sab10a0101r” 这个属性代表key,tags.DT_BB02_sab10a0101r就是key值
- 第二步,获取数据并填充到对应key中去
querySvgTableById() {
let data = {
plantId: this.powerPlantId,
unitId: this.unitId,
svgtableId: this.currentSort + 1,
};
querySvgTableById(data).then((res) => {
this.svgData = res.data;
this.svgInfo();
});
},
svgInfo() {
try {
if (this.indexA != 0) {
let Econtent = document.getElementById("e-content");
let temp = document.getElementById("svgWrap");
Econtent.removeChild(temp);
}
this.indexA++;
let svg = "";
if (this.currentSort == 0) {
svg = require(`@/assets/svg/dtbb.svg`);
} else if (this.currentSort == 1) {
svg = require(`@/assets/svg/dtbb1.1.svg`);
} else if (this.currentSort == 2) {
svg = require(`@/assets/svg/dtbb1.2.svg`);
}
this.renderAsSvg(svg);
} catch (err) {
this.hasSvg = false;
}
},
async renderAsSvg(url) {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.send();
xhr.addEventListener("load", async () => {
const resXml = xhr.responseXML;
this.svgDom = resXml.documentElement.cloneNode(true);
const oSerializer = new XMLSerializer();
const paths = this.svgDom.getElementsByTagName("path");
for (const item of paths) {
if (item.attributes.d.value) {
item.attributes.d.value = item.attributes.d.value.replace(
/[\r|\n]/g,
""
);
}
}
const text = this.svgDom.getElementsByTagName("text");
const textIds = [];
for (const item of text) {
if (item.innerHTML === "--") {
item.innerHTML = "@";
textIds.push(item.id);
}
}
await this.getSvgData(textIds);
const sXml = oSerializer.serializeToString(this.svgDom);
if (this.indexA == 1) {
const Profile = Vue.extend({
template: `<div id='svgWrap' style="margin-top:10px;">${sXml}</div>`,
});
new Profile().$mount("#e-content2");
} else {
var temp = document.createElement("div");
temp.id = "svgWrap";
temp.innerHTML = `${sXml}`;
document.getElementById("e-content").appendChild(temp);
}
// const Profile = Vue.extend({
// template: `<div id='svgWrap' style="margin-top:10px;">${sXml}</div>`,
// });
// new Profile().$mount("#e-content");
this.PSC(sXml);
for (let item in this.textIds) {
var s = document.getElementById(this.textIds[item]);
}
});
xhr.addEventListener("error", (err) => {
this.svgDom = null;
// this.hasSvg = false;
});
},
PSC(el) {
this.el = el;
this.prefix = {
tagName: "tagTextName__", // 测点名称的前缀
tagVal: "tagTextVal__", //测点值的前缀
tagUnit: "tagTextUnit__", //测点单位的前缀
tagState: "multistate__", //测点状态的前缀
};
/**
* 删除PB的标签
*/
// this.delPbLabel = function(){
var me = this;
var $svgDiv = $("svg");
// var $svgDiv = me.el;
$("defs").remove();
// $("pb\\:dataset").remove();
$("desc").remove();
$svgDiv.find("script").remove();
// $svgDiv.find('svg:first').attr('xmlns', "http://www.w3.org/2000/svg").attr('version', "1.0");
$svgDiv.attr("xmlns", svgPath).attr("version", '1.0').attr("id",this.currentSort+'_'+this.indexA).attr("PB:pid",'');
$svgDiv.removeAttr("xmlns:pbi").removeAttr("xmlns:pbd")
// $('rect,g,polygon,line,polyline,text,path').each(function(i, item){
$("rect,g,polygon,line,polyline,text,path").each(function (i, item) {
if (item.getAttribute("PB:Type") != null) {
$(item).attr("pbtype", item.getAttribute("PB:Type"));
}else if(item.getAttribute("pb:type") != null){
$(item).attr("pbtype", item.getAttribute("pb:type"));
}
if (item.getAttribute("PBD:PtTagName") != null) {
$(item).attr("pbdpttagname", item.getAttribute("PBD:PtTagName"));
}else if(item.getAttribute("pbd:pttagname") != null){
$(item).attr("pbdpttagname", item.getAttribute("pbd:pttagname"));
}
if (item.getAttribute("PB:IsMultiState") != null) {
$(item).attr("pbismultistate", item.getAttribute("PB:IsMultiState"));
}else if(item.getAttribute("pb:ismultistate") != null){
$(item).attr("pbismultistate", item.getAttribute("pb:ismultistate"));
}
// $(item).attr('pbtype', $(item).attr('pb:type')) // pb类型
// .attr('pbdpttagname', $(item).attr('pbd:pttagname')) //测点名
// .attr('pbismultistate', $(item).attr('pb:ismultistate')); // 是否状态
// item.attr('pbtype', item.attr('pb:type')).attr('pbdpttagname', item.attr('pbd:pttagname')).attr('pbismultistate', item.attr('pb:ismultistate'));
});
// 移除文本组中的rect标签
$svgDiv.find("g[pbtype='4'],g[pbtype='7']").find("rect").remove();
$("svg")
.removeAttr("pb:pid")
.removeAttr("xsi:schemalocation")
.removeAttr("image-rendering")
.removeAttr("xlink:xid")
.removeAttr("xmlns:svg")
.removeAttr("xmlns:BP")
.removeAttr("xmlns:PBI")
.removeAttr("xmlns:PBD")
.removeAttr("xmlns:xsi")
.removeAttr("onload");
// 移除带冒号的pd属性
$("rect,g,polygon,line,polyline,text,path")
.removeAttr("pb:docmajorversionnum")
.removeAttr("PB:docminorversionnum")
.removeAttr("PB:Docgroup")
.removeAttr("PB:Wnheight")
.removeAttr("PB:Wnwidth")
.removeAttr("PB:Wnstate")
.removeAttr("PB:Zoom")
.removeAttr("PB:Type")
.removeAttr("pb:type")
.removeAttr("PB:Namedvalues")
.removeAttr("PB:IsMultiState")
.removeAttr("PB:Visible")
.removeAttr("pb:visible")
.removeAttr("PB:Lineends")
.removeAttr("PB:LineStyle")
.removeAttr("PB:Strikethroughandunderline")
.removeAttr("PB:Fillcolor")
.removeAttr("PB:Fillstyle")
.removeAttr("PB:Backgroundcolor")
.removeAttr("PB:Tbhandle")
.removeAttr("PB:Rotation")
.removeAttr("PB:Flip")
.removeAttr("PB:Scripting")
.removeAttr("pb:scripting")
.removeAttr("PB:Archeight")
.removeAttr("PB:Arcleft")
.removeAttr("PB:Arcwidth")
.removeAttr("PB:Arctop")
.removeAttr("PB:Endangle")
.removeAttr("PB:Linecolor")
.removeAttr("PB:Startangle")
.removeAttr("PB:Endpoints")
.removeAttr("PB:Arcleft")
.removeAttr("PB:Localid")
.removeAttr("PB:Displayservertimezone")
.removeAttr("PB:Displaypointname")
.removeAttr("PB:Displaytimestamp")
.removeAttr("PB:Showuom")
.removeAttr("PB:Numberformat")
.removeAttr("PBD:Pttagname")
.removeAttr("PB:Persiststring")
.removeAttr("PB:Pttagtime")
.removeAttr("PB:Pttagstatus")
.removeAttr("PB:Pttagvalue")
.removeAttr("PBD:Property")
.removeAttr("PB:Flow")
.removeAttr("PB:Lower")
.removeAttr("PB:Orientation")
.removeAttr("PB:Start")
.removeAttr("PB:Upper")
.removeAttr("PB:horzalign");
// console.log("$svgDiv=>",$svgDiv)
// }
/**
* 测点值的展示信息定位
*/
// this.addTagInfo = function(){
// var me = this;
// var $svgDiv = $('#'+me.el);
var regStr = /\\{2}.+\\{1}/g;
// 找到所有标记测点值的地方
$svgDiv.find("g[pbtype='7']").each(function (i, item) {
var $item = $(item);
var tagName = $item
.attr("pbdpttagname")
.replace(regStr, "")
.toUpperCase();
if (me.svgData[i].key == tagName) {
$item
.find("text")
.attr("id", me.prefix.tagVal + tagName)
.attr("type", "tagTextVal")
.attr("tagname", tagName)
.text(me.svgData[i].value);
}
me.textIds.push(tagName);
var tagTextValX = $item.find("text").attr("x");
tagTextValX = tagTextValX ? parseFloat(tagTextValX) : undefined;
$item.siblings().each(function (i2, item2) {
var $text2 = $(item2).find("text");
if (tagTextValX) {
// 根据坐标定位测点名称和单位
var tagTextX = parseFloat($text2.attr("x"));
if (isNaN(tagTextX)) return false;
if (tagTextX < tagTextValX) {
me.textName.push($(item2).find("text")[0].innerHTML);
$text2
.attr("id", me.prefix.tagName + tagName)
.attr("type", "tagTextName");
} else if (tagTextX > tagTextValX) {
$text2
.attr("id", me.prefix.tagUnit + tagName)
.attr("type", "tagTextUnit");
}
} else {
// 没有坐标默认第一个为名称,第二个为单位
if (i2 == 0) {
$text2
.attr("id", me.prefix.tagName + tagName)
.attr("type", "tagTextName");
} else if (i2 == 1) {
$text2
.attr("id", me.prefix.tagUnit + tagName)
.attr("type", "tagTextUnit");
}
}
});
});
$svgDiv.find("g[pbtype='7']").each(function (i, item) {
});
// 找到状态位
$svgDiv.find("[pbismultistate='True']").each(function (i, item) {
var $item = $(item);
var pbdpttagname = $item.attr("pbdpttagname");
pbdpttagname = pbdpttagname
? pbdpttagname
: $item.find("pb\\:multistate").attr("pbd:pttagname");
if (pbdpttagname) {
var tagName = pbdpttagname.replace(regStr, "").toUpperCase();
if (tagName && tagName != "") {
$item
.attr("id", me.prefix.tagState + tagName)
.attr("type", "pb_multistate")
.attr("tagname", tagName);
}
}
});
// }
/**
* 初始化viewbox
*/
// this.doInitViewBox = function(){//处理初始化的viewbox
// var me = this;
var $svg = $(me.divId).find("svg:first");
var initViewBoxValues = [];
var $rect = $svgDiv.find("rect[pbtype='55']");
initViewBoxValues.push(0);
initViewBoxValues.push(0);
initViewBoxValues.push(185);
initViewBoxValues.push(185);
$svgDiv.get(0).setAttribute("viewBox", initViewBoxValues.join(" "));
// }
return true;
},
async getSvgData(keys) {
const params = {
tags: [],
codes: [],
};
keys.forEach((item) => {
if (item.includes("__")) {
const paramsKey = item.split("__")[1]; //__
paramsKey.includes("TAGS") || paramsKey.includes("CALS")
? params.tags.push(paramsKey)
: paramsKey.includes("TOTAL")
? params.codes.push(paramsKey)
: "";
}
});
},
每一步操作是什么意思备注中都已标注,如果有更好的方法,欢迎留言讨论。