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

Activate validation when the scope of a custom validator is modified

Consider a scenario where we have a custom validator with an input as the attribute's value. app.directive('inputRequired', function() { return { require: 'ngModel', scope: { inputRequired: '=& ...

Analyzing two arrays and utilizing ng-style to highlight matching entries within the arrays

My list displays words queried from a database, allowing me to click on a word to add it to another list that I can save. This functionality enables me to create multiple word lists. My goal is to visually distinguish the words in my query list that have a ...

What is the process for generating an SVG Icon using an SVG image in material ui?

Hey there, I've been working on creating a customized Svgicon myself. However, all of the existing source codes seem to directly use paths. Is there any way for me to incorporate an SVG icon from an image like this? import { SvgIcon } from '@mat ...

Utilize the capabilities of the Dropbox Core API in Javascript to effortlessly transfer and store files on

I am currently developing a chrome-extension that has the ability to upload files to the user's Dropbox folder. I have implemented AJAX requests in my code to handle file uploads, and it is working fine for text-based file extensions such as .txt, .js ...

React - Although the array in the state is being updated, only the first object in the array is visible on the screen

I'm currently working on developing a web application using the PokeAPI. My primary objective is to retrieve and display a variety of Pokemon based on their type. At the moment, I've set my API URL to specifically fetch fire type Pokemon. Howeve ...

My chart's data gets misaligned when I resize the window, causing issues with the d3

I have 5 HTML elements with the class "container" that will contain 5 SVG images. The ids of these elements are generated programmatically and consist of numbers: <div id="svg-container-total"></div> <div id="svg-container-3"></div> ...

Issue with Angular Factory not being invoked

I am currently using a tutorial to create a MEAN app with Google Maps. However, I have encountered an issue where the map is not appearing on the page. Surprisingly, there are no errors in the browser console and even when debugging with node-inspector, I ...

What is the best way to extract the primary base64 value from reader.result?

After successfully retrieving the base64 value of my file, I noticed that along with the value, I am also getting the type of file and the type of string. However, I only require the actual value in order to send it to the backend. Code for converting fil ...

The useEffect hook is executed only once and will not fetch data again upon refreshing the page

There's this component in my project that fetches data from a website and attempts to extract its keys. The issue I'm facing is that it functions correctly the first time, but upon refreshing the page or saving the project in VSCode (which trig ...

Adding points to a bar or pie chart in a Vue environment can be achieved dynamically by utilizing Vue's reactivity system

Looking to bootstrap a Highcharts bar chart and dynamically add points to it within a Vue container, the documentation references addPoint(), setData(), and update(). However, I struggled to make any of these methods work. The provided demo for updating a ...

Vue: Optimizing JSON response filtering

I am struggling with filtering a JSON response using Vue. return this.offers.filter(type => type.offers == 'Junior'); When I keep it as return this.offers, the following is displayed in my HTML: {"-MN5agCddYAdy7c8GSSz": { "comp ...

Displaying the format when entering a value with react-number-format

How to Display Format Only After Full Value Inserted in react-number-format I recently implemented the react-number-format package for formatting phone numbers. import { PatternFormat } from 'react-number-format'; <PatternFormat value={v ...

Interactive calendar control for selecting dates in JavaScript

I have implemented two date inputs in my PHP form: Arrival Date Departure Date Currently, when the Date Icon is selected, it displays the CURRENT DATE AND MONTH. What I am looking for is that when the user selects the Arrival Date first and then the De ...

What's the best way to organize a list while implementing List Rendering in VueJS?

Currently, I am working on List Rendering in Vue2. The list is rendering correctly, but it appears ordered based on the data arrangement in the array. For better organization, I need to sort each item alphabetically by title. However, I am facing difficult ...

Is your Angular5 service failing to transmit data?

I have two components in my code, A and B. Component A contains a form with data that I want to send to component B. However, it seems like component B is not receiving any data. Here is the code for Component A: import { MyService } from 'path/my ...

Why is the toggle list not functioning properly following the JSON data load?

I attempted to create a color system management, but as a beginner, I find it quite challenging! My issue is: When I load my HTML page, everything works fine. However, when I click on the "li" element to load JSON, all my toggle elements stop working!!! ...

issue with using references to manipulate the DOM of a video element in fullscreen mode

My current objective is to detect when my video tag enters fullscreen mode so I can modify attributes of that specific video ID or reference. Despite trying various methods, I have managed to log the element using my current approach. Earlier attempts with ...

The Nuxt image keeps disappearing every time I navigate to a new page

Whenever I have an image displayed on my Nuxt page and then navigate away from it, the image breaks and I can't figure out why. This is what my code looks like: <img :src="baseUrl + 'storage/'+ front.featured_image" alt="p ...

Is JavaScript the Key to Navigating Through a Website?

I am faced with the challenge of creating a script to extract a database from a website. The website's main page features a table where each row contains a link to another page that holds the desired database. Currently, my script can successfully e ...

conceal specific language options within the dropdown selection box

In my user interface, I have implemented a drop-down menu that allows users to select their preferred language. I want the selected language option to disappear from the drop-down menu once chosen. Here is the HTML code snippet: <li> < ...