Home > Enterprise >  difficult to put code in one svg (svg graph)
difficult to put code in one svg (svg graph)

Time:11-26

I have been working on a stacked barchart for quite some time and i think i have a messy code where i had used <svg> at 2 places for this one chart.

Please refer to this codepen https://codepen.io/a166617/pen/dyzEvMG I tried putting it under one svg tag so that the code looks lot sorted and better but i am unsuccessful. Any number of iterations to put the code in one svg tag has resulted in either messing up with the code even more and sometimes the barchart doesnot show up at all with my changes.

Can someone please let me know how to fix this mess i created. Would really appreciate any inputs on this.

The most important mess is the below code where i had put svg for each individual barchart.

{entries.map((entry, indx) => (
        <div class="mGraph content-style" key={Math.random()}>
          <svg
            viewBox={`0, 0, 80, 450`}
            height={500}
            width={90}
            style={{ transform: `rotateX(180deg)` }}
          >
            {rows(entry)}
          </svg>
          <div class="x-title">{entry.name}</div>
          { indx === 1 && <text class="label-title">PROJECTS</text>}
        </div>
))}

I tried reorganizing the code and here is the codepen for it https://codepen.io/a166617/pen/NWvZGLd

CodePudding user response:

I tried to do it using plain JS. Was able to create a single SVG for the graph:

const svgNS = "http://www.w3.org/2000/svg";

const addLine = (parent_g, x1, x2, y1, y2) => {
  var line = document.createElementNS(svgNS, "line");
  line.setAttribute("x1", x1);
  line.setAttribute("y1", y1);
  line.setAttribute("x2", x2);
  line.setAttribute("y2", y2);
  parent_g.appendChild(line);
};

const addText = (parent_g, x, y, text_val, class_ = "", dy = "", textanchor="", transform="") => {
  var text = document.createElementNS(svgNS, "text");
  text.setAttribute("x", x);
  text.setAttribute("y", y);
  
  if (class_ !== "")
    text.classList.add(class_);
  
  if (dy !== "")
    text.setAttribute("dy", dy);
    
  if (textanchor !== "")
    text.setAttribute("textAnchor", textanchor);
    
  if (transform !== "")
    text.setAttribute("transform", transform);
    
  text.innerHTML = text_val;
  parent_g.appendChild(text);
};

const addRect = (parent_g, width, height, x, y, fill) => {
    var rect = document.createElementNS(svgNS, "rect");
    rect.setAttribute("width", width);
    rect.setAttribute("height", height);
    rect.setAttribute("x", x);
    rect.setAttribute("y", y);
    rect.setAttribute("fill", fill);
    parent_g.appendChild(rect);
};

const addBarsToGraph = (entries) => {
  const barWidth = 50;
  const maxBarHeight = 490;
  
  var svgGraph = document.getElementById("svg-graph");
  
  var xpos = 100;
  for (var i = 0; i < entries.length; i  )
  {
    //console.log(entries[i].bars);
    for (var j = 0; j < entries[i].bars.length; j  )
    {
        const height = (entries[i].bars[j].value * maxBarHeight) / entries[i].total;
        const y = maxBarHeight - height - ((entries[i].bars[j].y * maxBarHeight) / entries[i].total);
        //console.log(height, y);
        addRect(svgGraph, 50, height, xpos, y, entries[i].bars[j].color);
        addText(svgGraph, xpos   15, y   height / 2 - 10, entries[i].bars[j].value, "bar-count", "1.3em", "middle");
    }
    //console.log(xpos, maxBarHeight   50);
    
    //var graphLabel = document.createElementNS(svgNS, "g");
    var rotateStr = "rotate(-45,"  xpos   ","   (maxBarHeight   50)   ")";
    addText(svgGraph, xpos, maxBarHeight   50, entries[i].name, "x-title", "", "middle", rotateStr);
    
    //svgGraph.appendChild(graphLabel);
    
    xpos  = 60;
  }
};

const addGridLinesAndGraphLabel = () => {
  var rootDiv = document.getElementById("root");
  rootDiv.style.display = "flex";
    
  var svg = document.createElementNS(svgNS, "svg");
  svg.setAttribute("id", "svg-graph");
  svg.classList.add("graph");
  
  var xgrid = document.createElementNS(svgNS, "g");
  xgrid.classList.add("grid");
  xgrid.classList.add("x-grid");
  xgrid.setAttribute("id", "xGrid");
  addLine(xgrid, "90", "90", "5", "490");
  svg.appendChild(xgrid);
  
  var ygrid = document.createElementNS(svgNS, "g");
  ygrid.classList.add("grid");
  ygrid.classList.add("y-grid");
  ygrid.setAttribute("id", "yGrid");
  addLine(ygrid, "90", "1805", "490", "490");
  svg.appendChild(ygrid);
  
  var ylabels = document.createElementNS(svgNS, "g");
  ylabels.classList.add("labels");
  ylabels.classList.add("y-labels");
  addText(ylabels, "80", "15", 100);
  addText(ylabels, "80", "131", 75);
  addText(ylabels, "80", "248", 50);
  addText(ylabels, "80", "373", 25);
  addText(ylabels, "80", "500", 0);
  addText(ylabels, "60", "200", "Pass %", "label-title");
  svg.appendChild(ylabels);
  
  addText(svg, "500", "550", "PROJECTS", "label-title");
  
  rootDiv.appendChild(svg);
};

const ReleaseScopeCharts = () => {
  const data = [
    {
      name: 'Transit',
      passed: 20,
      skipped: 50,
      failed: 30,
      untested: 0
    },
    {
      name: 'Access',
      passed: 0,
      skipped: 0,
      failed: 0,
      untested: 100
    },
  ];

  const colors = ['#30D158', '#005EA7', '#FF453A', '#ffcc00'];
 
  const entries = data.map(d => ({
    name: d.name,
    total: ['passed', 'skipped', 'failed', 'untested'].reduce(
      (acc, key) => acc   d[key],
      0
    ),
    bars: ['passed', 'skipped', 'failed', 'untested']
      .map((key, i) => ({
        value: d[key],
        color: colors[i],
        y:
          key === 'passed'
            ? 0
            : key === 'skipped'
            ? d.passed
            : d.skipped   d.passed,
      }))
      .filter(bar => bar.value),
    }));
        
    addGridLinesAndGraphLabel();
    addBarsToGraph(entries);
    
};

window.onload = () => { ReleaseScopeCharts(); }
body {
  font-family: 'Open Sans', sans-serif;
  margin-top: 1rem;
}

.mGraph > svg {
  position: relative;
  left: -60rem;
  top: -.65rem;
}

.mGraph > div {
  position: relative;
  left: -58rem;
  top: -.65rem;
}

.mGraph > text {
  position: relative;
  left: -50rem;
}

.graph .labels.x-labels {
  text-anchor: middle;
}

.graph .labels.y-labels {
  text-anchor: end;
}


.graph {
  height: 600px;
  width: 1200px;
}

.graph .grid {
  stroke: #ccc;
  stroke-dasharray: 0;
  stroke-width: 1;
}

.labels {
  font-size: 13px;
}

.label-title {
  font-weight: bold;
  text-transform: uppercase;
  font-size: 12px;
  fill: black;
  margin-left: 50%
}

.data {
  fill: red;
  stroke-width: 1; 
}

.bar-count {
  fill: white;
  font-size: 12px;
  transform-box: fill-box;
  transform: rotateX(0deg)
}

.x-title {
    color: red;
    margin-top: 20%;
    /*transform: rotate(-45deg)*/
};

.content-style {
  display: flex;
  flex-flow: column;
  align-items: center;
}
<!DOCTYPE html>
<div id="root"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related