我一生都无法找出如何使用由始终变化的 XML 文档定义的变量在 svg 多边形上设置点,或者是否可能。
我只想按照
的方式设置路径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);
}
可以输入的变量有: 身高:34 宽度:12 类型:1 深度:12 宽度:34 Cstmr:3.5 越南盾:4 jw:4.5规模 jh:1.75比例 x=0 y=0
正如评论所述,您当前的脚本不会创建要应用于
<polygon>
点属性的有效点数组。
假设 XML 解析工作正常,并且您的坐标缩放部分的点坐标应如下所示:
// create polygon point array
let 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 - 0.75) * scale), (by + dy + (Height - 2.5) * scale),
(bx + (depth - Cstmr - 0.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)
];
// set points to polygon attribute
brjambshape.setAttribute("points", points.join(' '));
当前代码中的主要问题:您没有用逗号分隔 x 和 y 坐标。
附注:svg 元素不需要
createElementNS()
,除非它们使用自定义命名空间(许多图形应用程序使用这些来存储应用程序特定的元数据 - 浏览器显示不需要)。
let 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>
<JH>1.75</JH>
<Width>12</Width>
<Height>34</Height>
<BHeight>2</BHeight>
<BWidth>2</BWidth>
<TYPE>4</TYPE>`;
// parse xml to JS object
let instanceData = xmlStringToJSO(xml);
// properties to variables
let {
Width,
Height,
Depth,
BWidth,
Cstmr,
Vndr,
BHeight,
TYPE
} = instanceData;
// create svg
let svgns = "http://www.w3.org/2000/svg";
var svg = window.document.createElementNS(svgns, "svg");
svg.setAttribute("height", Height);
svg.setAttribute("width", Width);
var b = (Width < Height ? Width : Height) / 10;
var bx = b;
var by = b;
var dx = Width - b * 2;
var dy = Height - b * 2;
var scalew = (dx / Width) * 0.75;
var scaleh = (dy / Height) * 0.75;
var scale = scalew < scaleh ? scalew : scaleh;
bx += (dx - Width * scale) / 2;
by -= (dy - Height * scale) / 2;
var depth = Depth;
var bWidth = BWidth;
var jw = 4.5 * scale;
var x = 0;
var y = 0;
let brJambGroup = document.createElementNS(svgns, "g");
brJambGroup.id = "mygroup";
let basegroup = document.createElementNS(svgns, "g");
basegroup.id = "baseGroup";
var brjambshape = document.createElementNS(svgns, "polygon");
// create polygon point array
let 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 - 0.75) * scale), (by + dy + (Height - 2.5) * scale),
(bx + (depth - Cstmr - 0.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)
];
// set points to polygon attribute
brjambshape.setAttribute("points", points.join(' '));
brjambshape.setAttribute("stroke", "red");
brjambshape.setAttribute("fill", "none");
brJambGroup.appendChild(brjambshape);
if (TYPE.toString() == "4") {
svg.appendChild(basegroup);
//svg.appendChild(nbrjambgroup);
svg.appendChild(brJambGroup);
}
document.body.append(svg)
// adjust viewBox
let bb = svg.getBBox();
svg.setAttribute('viewBox', [bb.x, bb.y, bb.width, bb.height].join())
/**
* xml to JSO helper
*/
function xmlStringToJSO(xmlString) {
const xml2Jso = (xml) => {
try {
var obj = {};
if (xml.children.length > 0) {
for (var i = 0; i < xml.children.length; i++) {
var item = xml.children.item(i);
var nodeName = item.nodeName;
if (typeof(obj[nodeName]) == "undefined") {
obj[nodeName] = xml2Jso(item);
} else {
if (typeof(obj[nodeName].push) == "undefined") {
// convert to numbers
var val = isFinite(obj[nodeName]) ? parseFloat(obj[nodeName]) : obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(val);
}
obj[nodeName].push(xml2Jso(item));
}
}
} else {
obj = isFinite(xml.textContent) ? parseFloat(xml.textContent) : xml.textContent;
}
return obj;
} catch (e) {
console.log(e.message);
}
}
let xmlDoc = new DOMParser().parseFromString(`<xmlroot>${xmlString}</xmlroot>`, "text/xml").querySelector('xmlroot')
let jso = xml2Jso(xmlDoc)
return jso;
}
如果您的数据源(应用程序/API)还提供 JSON 导出,请首选此选项,因为它可以简化数据解析。