svg 绘制流程图
用到的知识svg marker(结合marker-end), path上使用marker-end指向定义defs中的marker这个比较厉害箭头Vue.component('flowMapGuide', {template: `<div><svg ref="rootSvg" xmlns="http://www.w3.org/2
·
用到的知识svg marker(结合marker-end), path上使用marker-end指向定义defs中的marker这个比较厉害箭头
Vue.component('flowMapGuide', {
template: `<div>
<svg ref="rootSvg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:block;margin: 0 auto">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="2" refY="3" orient="auto" markerUnits="strokeWidth" fill="rgb(128,128,128)"> <path d="M0,0 L0,6 L9,3 z"/>
</marker>
</defs>
</svg>
</div>`,
props: {
flowMapParam: {
required: true
}
},
data: function() {
return {
MAP_JSON: null,
svgSizePx: {
width: 0,
height: 0
},
size: {
x: 0,
y: 0
},
endLineStep: [],
perMapSizePX : {
x: 150, //宽
y: 60, //高
rx: 0,
gapX: 60,
gapY: 28
}
}
},
mounted: function() {
var self = this;
/*requestFunc("/c/userinfo/queryflowmap", {SEQ: this.flowMapParam.SEQ}, true).then(function(flowMapObj) {
try {
var MAP_JSON = JSON.parse(flowMapObj.MAP_JSON);
} catch(err) {
console.log(err);
}*/
var MAP_JSON = {"body":[[{"id":"pressureInteractionDevice","seq":"1","title":"压感设备定义","optionFlag":"must","widgetType":"rectangle","pageUrl":"pages/ydCommerce/pressureInteraction/pressureInteractionDevice.html","progCode":"pressureInteractionDevice","moduleName":"online","icon":"goodsProperty","parentId":"upBasicData-3"}],[{"id":"fodderManage","seq":"1","title":"商品视频上传","optionFlag":"must","widgetType":"rectangle","pageUrl":"pages/ydCommerce/putIn/fodderManage.html","progCode":"fodderManage","moduleName":"ad","icon":"upGoodsPic"},{"id":"styleVideoUpload","seq":"2","title":"商品视频选择","optionFlag":"must","widgetType":"rectangle","pageUrl":"pages/ydCommerce/pressureInteraction/styleVideoUpload.html","progCode":"styleVideoUpload","moduleName":"online","icon":"fodderManage"},{"id":"upGoodsPic","seq":"3","title":"商品图片上传","optionFlag":"must","widgetType":"rectangle","pageUrl":"pages/goods/langWan/upGoodsPic.html","progCode":"upGoodsPic","moduleName":"goods","icon":"upGoodsPic","parentId":"upBasicData-3"}],[{"id":"pressureInteractionService","seq":"1","title":"压感商品投放","optionFlag":"must","widgetType":"rectangle","pageUrl":"pages/ydCommerce/pressureInteraction/pressureInteractionService.html","progCode":"pressureInteractionService","moduleName":"online","icon":"hotGoodsService-2","parentId":"upBasicData-3"}],[{"id":"fsAdService","seq":"1","title":"广告投放","optionFlag":"must","widgetType":"rectangle","pageUrl":"pages/fittingSystem/putIn/adService.html","progCode":"fsAdService","moduleName":"AD","icon":"adService","parentId":"upBasicData-3"}]],"footer":[{"id":"upBasicData-3","seq":"2","title":"资料上传-生成终端DB","optionFlag":"must","widgetType":"rectangle","pageUrl":"pages/goods/langWan/upBasicData.html","progCode":"upBasicData","moduleName":"goods","icon":"upBasicData-3","parentId":""}]}
self.MAP_JSON = self.mapJsonFormat(MAP_JSON);
self.computedMapSize();
self.drawMap();
/*});*/
},
methods: {
mapJsonFormat: function(mapJson) {
return mapJson;
},
computedMapSize: function() {
var x = this.MAP_JSON.body.length;
var y = 0;
for(var i=0;i<this.MAP_JSON.body.length;i++) {
if(y<this.MAP_JSON.body[i].length) {
y = this.MAP_JSON.body[i].length;
}
}
if(x<this.MAP_JSON.footer.length) {
x = this.MAP_JSON.footer.length;
}
this.size.x = x+1;
this.size.y = y+1;
var rootSvg = this.$refs.rootSvg;
rootSvg.setAttribute("style", "display:block;margin: 0 auto;")
this.svgSizePx.width = (this.size.x-1)*this.perMapSizePX.x+(this.size.x-2)*this.perMapSizePX.gapX+20;
this.svgSizePx.height = this.size.y*this.perMapSizePX.y+this.size.y*this.perMapSizePX.gapY+20;
rootSvg.setAttribute("width", this.svgSizePx.width);
rootSvg.setAttribute("height", this.svgSizePx.height);
},
drawMap: function() {
var rootSvg = this.$el.getElementsByTagName("svg")[0];
//计算起点
if(this.MAP_JSON.footer.length<this.size.x-1) {
this.drawFooter(rootSvg, (this.size.x-1-this.MAP_JSON.footer.length)*(this.perMapSizePX.x+this.perMapSizePX.gapX)/2);
} else {
this.drawFooter(rootSvg, 0);
}
//计算起点
if(this.MAP_JSON.body.length<this.size.x-1) {
this.drawBody(rootSvg, (this.size.x-1-this.MAP_JSON.body.length)*(this.perMapSizePX.x+this.perMapSizePX.gapX)/2);
} else {
this.drawBody(rootSvg, 0);
}
},
drawBody: function(rootSvg, offsetLeft) {
var rows = this.MAP_JSON.body;
for(var i=0;i<rows.length;i++) {
var curColumns = rows[i];
for(var j=0;j<curColumns.length;j++) {
var opt = {
x: 10+i*(this.perMapSizePX.x+this.perMapSizePX.gapX)+offsetLeft,
y: 10+j*(this.perMapSizePX.y+this.perMapSizePX.gapY)
}
Object.assign(opt, curColumns[j]);
if(j==curColumns.length-1) {
var g = this.createg(opt, j);
} else {
var g = this.createg(opt);
}
rootSvg.append(g);
}
}
},
createg: function(opt, endY) {
var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.setAttribute("transform", 'translate('+(opt.x+0.5)+","+(opt.y+0.5)+')');
g.setAttribute("title", opt.title);
g.setAttribute("name", opt.progCode);
g.setAttribute("url", opt.pageUrl);
//创建一个框
if(opt.widgetType == "rectangle") {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("width", this.perMapSizePX.x);
rect.setAttribute("height", this.perMapSizePX.y);
rect.setAttribute("rx", this.perMapSizePX.rx);
rect.setAttribute("ry", this.perMapSizePX.rx);
rect.setAttribute( "fill", "rgb(255,255,255)");
rect.setAttribute( "stroke-width", 1);
rect.setAttribute( "stroke", "rgb(148,148,148)");
} else {
var d = 'M0 0 l'+this.perMapSizePX.x+' 0 l0 '+this.perMapSizePX.y+'C'+(this.perMapSizePX.x-this.perMapSizePX.x/8)+' '+(this.perMapSizePX.y-10)+","+(this.perMapSizePX.x-3*this.perMapSizePX.x/8)
+" "+(this.perMapSizePX.y-10)+","+this.perMapSizePX.x/2+" "+this.perMapSizePX.y+"S"+(this.perMapSizePX.x/8) +" "+(this.perMapSizePX.y+10)+",0 "+this.perMapSizePX.y+" Z";
var rect = document.createElementNS("http://www.w3.org/2000/svg", "path");
rect.setAttribute("d", d);
rect.setAttribute("fill", "none");
rect.setAttribute( "stroke-width", 1);
rect.setAttribute( "stroke", "rgb(148,148,148)");
rect.setAttribute("widgetType", "document");
}
var foreignObject = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")
foreignObject.setAttribute("width", this.perMapSizePX.x);
foreignObject.setAttribute("height", this.perMapSizePX.y);
var des = opt.optionFlag == "must" ? "必填":"选填";
var foreignObjectInnerHTML = '<div class="outer">'+
'<div class="map-title">'+opt.title+'</div>'+
'<div class="tip">('+des+')</div>'+
'</div>';
foreignObject.innerHTML = foreignObjectInnerHTML;
var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
if(typeof endY == "undefined") {
path.setAttribute("d", 'M '+this.perMapSizePX.x/2+' '+this.perMapSizePX.y+" l 0 "+(this.perMapSizePX.gapY-8));
} else {
var matched = false;
for(var i=0;i<this.endLineStep.length;i++) {
if(this.endLineStep[i].parentId == opt.parentId) {
matched = true;
}
}
if(!matched) {
this.endLineStep.push({
parentId: opt.parentId,
endY: this.endLineStep.length*2
});
}
var endPointY;
for(var i=0;i<this.endLineStep.length;i++) {
if(this.endLineStep[i].parentId == opt.parentId) {
endPointY = this.endLineStep[i].endY;
break;
}
}
var rootSvg = this.$refs.rootSvg;
var endPointEle =rootSvg.getElementById(opt.parentId);
var point = {};
point.x = endPointEle.getAttribute("pointX");
point.y = endPointEle.getAttribute("pointY");
var d = 'M '+this.perMapSizePX.x/2+' '+this.perMapSizePX.y+' l 0 '+ (this.perMapSizePX.gapY+(this.perMapSizePX.gapY+this.perMapSizePX.y)*(this.size.y-2-endY)+this.endLineStep.length*4+endPointY) +' l '+(point.x-opt.x)+' 0'+"l 0 "+(20-endPointY*3);
path.setAttribute("d", d);
}
path.setAttribute("marker-end", "url(#arrow)");
path.setAttribute("style", "stroke:rgb(148,148,148);stroke-width:1;fill:none");
path.className="line";
var xmlns = "http://www.w3.org/2000/svg";
var oImg = document.createElementNS(xmlns,"image");
oImg.setAttributeNS('http://www.w3.org/1999/xlink','href', 'img/guidemap_icon/'+opt.icon+'.png');
oImg.setAttributeNS(null, "width", 30);
oImg.setAttributeNS(null, "height", 30);
oImg.setAttributeNS(null, "x", 10);
oImg.setAttributeNS(null, "y", 15);
g.appendChild(rect);
g.append(foreignObject);
g.append(path);
//g.appendChild(oImg);
return g;
},
drawFooter: function(rootSvg, offsetLeft) {
var curColumns = this.MAP_JSON.footer;
for(var i=0;i<curColumns.length;i++) {
var opt = {
x: 10+i*(this.perMapSizePX.x+this.perMapSizePX.gapX)+offsetLeft,
y: (this.size.y-1)*(this.perMapSizePX.y+this.perMapSizePX.gapY)+40
}
Object.assign(opt, curColumns[i]);
var g = this.createFooterCell(opt);
rootSvg.append(g);
}
},
createFooterCell: function(opt) {
var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.setAttribute("transform", 'translate('+(opt.x+0.5)+","+(opt.y+0.5)+')');
g.setAttribute("id", opt.id);
g.setAttribute("title", opt.title);
g.setAttribute("name", opt.progCode);
g.setAttribute("url", opt.pageUrl);
g.setAttribute("pointX", opt.x);
g.setAttribute("pointY", opt.y);
//创建一个框
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("width", this.perMapSizePX.x);
rect.setAttribute("height", this.perMapSizePX.y);
rect.setAttribute("rx", this.perMapSizePX.rx);
rect.setAttribute("ry", this.perMapSizePX.rx);
rect.setAttribute( "fill", "rgb(255,255,255)");
rect.setAttribute( "stroke-width", 1);
rect.setAttribute( "stroke", "rgb(148,148,148)");
var foreignObject = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")
foreignObject.setAttribute("width", this.perMapSizePX.x);
foreignObject.setAttribute("height", this.perMapSizePX.y);
var des = opt.optionFlag == "must" ? "必填":"选填";
var foreignObjectInnerHTML = '<div class="outer">'+
'<div class="map-title">'+opt.title+'</div>'+
'<div class="tip">('+des+')</div>'+
'</div>';
foreignObject.innerHTML = foreignObjectInnerHTML;
var xmlns = "http://www.w3.org/2000/svg";
/*var oImg = document.createElementNS(xmlns,"image");
oImg.setAttributeNS('http://www.w3.org/1999/xlink','href', 'img/guidemap_icon/'+opt.icon+'.png');
oImg.setAttributeNS(null, "width", 30);
oImg.setAttributeNS(null, "height", 30);
oImg.setAttributeNS(null, "x", 10);
oImg.setAttributeNS(null, "y", 15);*/
g.appendChild(rect);
g.append(foreignObject);
//g.appendChild(oImg);
return g;
}
}
});
<div id="app">
<flow-map-guide :flowMapParam="flowMapParam"></flow-map-guide>
</div>
更多推荐
已为社区贡献2条内容
所有评论(0)