I cannot for the life of me find out how, or if its even possible, to set points on an svg polygon using variables that are defined by an XML document that is always changing.
I just want to set the path to something along the lines of
var polygonIwant = window.document.createElementNS(svgns,"polygon");
polygonIwant.setAttributeNS(null,"points", "M"+var1+", "+var2+", L"+var3+" ...etc);
polygongroup.appendChild(polygonIwant);
is there just not a way to do this?
I tried what I put above, but kept getting errors when running it.
I'm using vanilla javascript, and its going into a report generated in jaspersoft studio.
I would even settle for being able to create a standard shape, and just have the shapes coordinates change. No idea if that is possible either.
XML Data:
<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>
variables:
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);
}
The variables that can be input are: Height: 34 Width: 12 Type: 1 depth: 12 bwidth: 34 Cstmr: 3.5 Vndr: 4 jw: 4.5scale jh: 1.75scale x=0 y=0
As commented the your current script doesn't create a valid point array to be applied to a <polygon>
point attribute.
Provided, the XML parsing works correctly as well as your coordinate scaling the part for the point coordinates should look something like this:
// 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(' '));
The main issue in your current code: you haven't separated x and y coordinates by a comma.
As a side note: you don't need createElementNS()
for svg elements unless they use a custom namespace (a lot of graphic applications use these to store app specific metadata - not needed for browser display).
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;
}
If your data source (application/API) also provides a JSON export, prefer this option as it simplifies data parsing.