Is there a way to utilize variables from a source XML file to establish points on an SVG polygon?

I've been struggling to figure out if it's possible to dynamically set points on an SVG polygon using variables that are defined by an XML document which is constantly changing.

All I want is to set the path like this:

var polygonToUse = window.document.createElementNS(svgns,"polygon");
polygonToUse.setAttributeNS(null,"points", "M"+var1+", "+var2+", L"+var3+" ...etc);
polygongroup.appendChild(polygonToUse);

Is there no way to achieve this?

I attempted what I described above, but encountered errors while running it.

I am working with pure JavaScript and integrating it into a report created in Jaspersoft Studio.

I would even be satisfied with creating a basic shape and updating its coordinates. Not sure if that's feasible 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 inputtable variables include: Height: 34 Width: 12 Type: 1 Depth: 12 Basewidth: 34 Customer: 3.5 Vendor: 4 jw: 4.5scale jh: 1.75scale x=0 y=0

Answer №1

It seems that the current script you are using does not generate a valid point array for the <polygon>'s point attribute.

If the XML parsing is functioning correctly and your coordinate scaling is accurate, the section responsible for defining the point coordinates should resemble the following:

// 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)
];
// assign points to the polygon attribute
brjambshape.setAttribute("points", points.join(' '));  

The primary issue in your code lies in the fact that you have not separated the x and y coordinates with a comma.

Additionally, it's worth noting that unless SVG elements use a custom namespace (often utilized by graphic applications for specific metadata), there is no need for createElementNS() when working with 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, opting for this choice can streamline data parsing processes.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I retrieve the $index value of an ng-repeat element within a uib-dropdown?

I am currently working on implementing an ng-repeat loop that includes a dropdown menu for each element. I want the dropdown menu to contain functions that operate on the specific element, requiring access to the index of that element. Below is the code sn ...

How can I prevent users from selecting text when they right click using JavaScript?

My custom context menu on canvas works well, but I'm facing an issue with Text elements. When I try to right-click on a text element, it triggers text selection as if double-clicking. I attempted to use the following code: document.addEventListener(& ...

Switching classes in real time with JavaScript

I'm struggling to understand how to toggle a class based on the anchor text that is clicked. <div> <a id="Menu1" href="#">Menu</a> <div id="subMenu1" class="subLevel"> <p>stuff</p> </div> <div> <a i ...

obtain data from JSON using JavaScript

Greetings! I am dealing with a JSON output that looks like this: "{ \"max_output_watts\": 150, \"frame_length_inches\": \"62.20\", \"frame_width_inches\": \"31.81\" }" I am using it in a functi ...

Perform a check on the state of the slideToggle using an if-else function and provide a report on the slideToggle state

http://jsfiddle.net/vmKVS/ I need some help understanding the functionality of slideToggle using a small example. After toggling for the first time, the options element changes color to green. However, I expected the menu element to turn red when I togg ...

Arrange a set of items using AngularJS according to specific criteria

Hello, I'm new to Angular I've created an angular app and you can view it in this plunkr. Can someone guide me on how to sort the list displayed here using angular? I want the course with the flag to always stay on top, while sorting the rest o ...

Troubleshooting: Unable to Remove Files in PhoneGap

I've been working on a basic app that heavily utilizes PhoneGap to test its capabilities. Currently, I'm trying to delete a file that has been downloaded within the app, but I'm encountering some issues. The majority of the code I've im ...

Tips for resolving the 'route.search' bug in Express.js

I recently started working on a basic Express app (with Node) and I am in the initial setup phase. However, I have encountered an error that is proving to be quite challenging to resolve. Despite my attempts to search for solutions online and browse throu ...

Creating an array of custom objects in JavaScript.Initializing custom objects in an

Is there a proper way to prevent the error "Cannot read property 'length' of undefined" when initializing an array of custom objects in javascript? situation export class MyClass implements OnInit { myArray: MyObject[]; } example <div ...

Converting a functional component into a class-based component

I am in the process of converting a functional based Component to a class-based Component and creating a PrivateAuth Component. Here is the original PrivateAuth functional Component. function PrivateRoute({ component: Component, ...rest }) { return ( ...

How can I retrieve the Google Maps URL containing a 'placeid' using AJAX?

I have a specific URL that I can access through my browser to see JSON data. The URL appears as follows: https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJZeH1eyl344kRA3v52Jl3kHo&key=API_KEY_HERE However, when I attempt to use jQuer ...

Difficulty comprehending the fallback for JSON.parse in jQuery.parseJSON

Check out the origin of $.parseJSON function (data) { if (typeof data !== "string" || !data) { return null; } // Remove leading/trailing whitespace for compatibility data = jQuery.trim(data); // Try native JSON parser first ...

Struggling with generating forms using AJAX, Javascript, and HTML depending on the selection made from a drop-down menu

I am in need of a simple web form for work submissions within my organization. These submissions will fit into 4 Categories, each requiring unique information. Currently, I have a basic form set up with fields such as Requested Name, Requested Date, Acquis ...

What is the most efficient way to use jQuery to retrieve the count of tags associated with a variable

I am trying to filter my data retrieved from ajax using a function. Here is the initial code: var csvf = data.filter(function (el) { return ['TRUCK_CPX'].indexOf(el.TAG) >= 0 && ['CA5533'].indexOf(el.Chave) >= 0 }); Now ...

including a close button when in use and excluding it when not in use

Seeking assistance with removing the "close" icon if it is not active. Here is the code I currently have $("#mason2 li div").click(function() { $(this).parent().hide().appendTo("#mason2").fadeIn(200); $(this).append('<p class="close"& ...

Getting the specific information you need from a JSON object in Angular 2

Struggling to extract specific data from a JSON file with nested objects like this: { "results" : [ { "address_components" : [ { "long_name" : "277", "short_name" : "277", "types" : [ "street_number" ] ...

Alter a prototype method belonging to another module

If I wanted to create a custom plugin or module that alters the behavior of an object exported in another module, how can I go about modifying one of its methods? The code below illustrates my attempt at achieving this, but it seems like there may be a cru ...

How can JavaScript be used to rearrange the placement of DOM elements?

<!DOCTYPE html> <html> <head> <title></title> </head> <body> <div class="boxes"> <div class="red" style="width: 300px; height: 300px; color: red"></div> <div class="blue ...

Implementing a dynamic function with jQuery Tokenize's change event

I'm currently facing an issue with triggering the on change event on the select box from jQuery Tokenize. Below is the code snippet I am working with: <select id="tokenize" multiple="multiple" class="tokenize-sample"> <option value="1"&g ...

What is the best method to securely install a private Git repository using Yarn, utilizing access tokens without the need to hardcode them

My initial thought was to utilize .npmrc for v1 or .yarnrc.yml for v2/3/4, but in all scenarios, Yarn does not even attempt to authenticate with Github. nodeLinker: node-modules npmScopes: packagescope: npmAlwaysAuth: true npmAuthToken: my_perso ...