如何用动态XML文档定义的变量设置SVG多边形points属性
动态通过XML变量设置SVG多边形points属性的实现问题
我一直找不到方法,甚至不确定能不能用动态XML文档里定义的变量来设置SVG多边形的points属性。我想按类似下面的方式设置路径:
var polygonIwant = window.document.createElementNS(svgns,"polygon"); polygonIwant.setAttributeNS(null,"points", "M"+var1+", "+var2+", L"+var3+" ...etc); polygongroup.appendChild(polygonIwant);
但尝试后运行一直报错,我用的是原生JavaScript,代码要用到Jaspersoft Studio生成的报表里。哪怕是先创建标准形状再修改坐标的方案我也能接受,但不确定是否可行。
XML数据
<mach_name>BASE-VISUALIZATION</mach_name> <mach_keywords>BASE-SHAPE</mach_keywords> <mach_keywords_list> <keyword>BASE-SHAPE</keyword> </mach_keywords_list> <Depth>12</Depth> <Cstmr>3.5</Cstmr> <Vndr>4</Vndr> <Bheight>2</Bheight> <TYPE>4</TYPE>
现有变量定义代码
var svg = window.document.createElementNS("http://www.w3.org/2000/svg","svg"); svg.setAttributeNS(null,"height",instanceData.height); svg.setAttributeNS(null,"width",instanceData.width); var b=((instanceData.width<instanceData.height)? instanceData.width:instanceData.height)/10; var bx=b; var by=b; var dx=instanceData.width-b*2; var dy=instanceData.height-b*2; var scalew=dx/width*.75; var scaleh=dy/height*.75; var scale=(scalew<scaleh)?(scalew):scaleh; bx+=(dx-width*scale)/2; by-=(dy-height*scale)/2; var depth=parseFloat(instanceData.Depth); var bwidth=parseFloat(instanceData.basewidth); var Cstmr=parseFloat(instanceData.Cstmr); var Vndr=parseFloat(instanceData.Vndr); var jw=4.5*scale var x=0 var y=0 brJambGroup=document.createElementNS(svgns,"g"); brJambGroup.setAttribute("name","mygroup"); var brjambshape = window.document.createElementNS(svgns,"polygon"); brjambshape.setAttributeNS(null, "points",(bx+(depth-Cstmr-4.5)*scale) (by+dy+height*scale), (bx+(depth-Cstmr)*scale) (by+dy+height*scale), (bx+(depth-Cstmr)*scale) (by+dy+(height-2.5)*scale), (bx+(depth- Cstmr-.75)*scale) (by+dy+(height-2.5)*scale), (bx+(depth- Cstmr-.75)*scale) (by+dy+(height-1.75)*scale), (bx+(depth-Cstmr- 4.5)*scale) (by+dy+(height-1.75)*scale), (bx+(depth-Cstmr-4.5)*scale) (by+dy+height*scale)); brjambshape.setAttributeNS(null, "stroke","red"); brjambshape.setAttributeNS(null,"fill","none"); brJambGroup.appendChild(brjambshape); if(TYPE.toString()=="4") { svg.appendChild(basegroup); //svg.appendChild(nbrjambgroup); svg.appendChild(brJambGroup); }
可输入变量列表
- Height: 34
- Width: 12
- Type: 1
- depth: 12
- bwidth: 34
- Cstmr: 3.5
- Vndr: 4
- jw: 4.5*scale
- jh: 1.75*scale
- x=0
- y=0
解决方案
1. 修正points属性的拼接错误
你现有代码里设置points时犯了字符串拼接的语法错误:坐标之间没有用+连接,也没有正确添加分隔符。SVG的points属性格式是空格或逗号分隔的坐标对(比如"x1 y1 x2 y2 x3 y3..."或"x1,y1 x2,y2..."),不需要M、L这类路径命令(那是<path>元素的d属性专用语法)。
修改后的points拼接代码示例:
// 用模板字符串拼接,自动处理分隔符 var pointsStr = ` ${bx+(depth-Cstmr-4.5)*scale},${by+dy+height*scale} ${bx+(depth-Cstmr)*scale},${by+dy+height*scale} ${bx+(depth-Cstmr)*scale},${by+dy+(height-2.5)*scale} ${bx+(depth-Cstmr-.75)*scale},${by+dy+(height-2.5)*scale} ${bx+(depth-Cstmr-.75)*scale},${by+dy+(height-1.75)*scale} ${bx+(depth-Cstmr-4.5)*scale},${by+dy+(height-1.75)*scale} ${bx+(depth-Cstmr-4.5)*scale},${by+dy+height*scale} `.replace(/\s+/g, ' ').trim(); // 清理多余换行和空格 brjambshape.setAttributeNS(null, "points", pointsStr);
2. 其他潜在问题修正
- 确保
svgns变量已正确定义:const svgns = "http://www.w3.org/2000/svg";,否则创建SVG元素会失败。 - 检查
height变量(小写)是否已定义:现有代码直接使用了height,但未看到声明,应该替换为instanceData.height或者提前定义该变量。 - 用
var/let声明brJambGroup,避免全局变量污染:let brJambGroup = document.createElementNS(svgns,"g");
3. 后期修改坐标的方案
如果要创建多边形后再修改坐标,直接重新设置points属性即可:
// 后期修改时,生成新的坐标字符串 var newPoints = "10,10 50,10 50,50 10,50"; brjambshape.setAttributeNS(null, "points", newPoints);
也可以用数组维护坐标,修改后再拼接成字符串,更灵活:
// 初始化坐标数组 var coords = [ [bx+(depth-Cstmr-4.5)*scale, by+dy+height*scale], [bx+(depth-Cstmr)*scale, by+dy+height*scale], // ...其他坐标 ]; // 拼接为points格式字符串 var pointsStr = coords.map(coord => coord.join(',')).join(' '); brjambshape.setAttributeNS(null, "points", pointsStr); // 修改某一个坐标后重新设置 coords[0][0] = 20; // 修改第一个点的x值 brjambshape.setAttributeNS(null, "points", coords.map(coord => coord.join(',')).join(' '));
内容的提问来源于stack exchange,提问作者StrugglingToCode
相关产品推荐
相关产品推荐

