Obtížné dát kód v jednom svg (svg graf)

0

Otázka

Pracoval jsem na skládaný barchart pro docela nějaký čas a myslím, že jsem chaotický kód, kde jsem použil <svg> na 2 místech pro tento jeden graf.

Podívejte se prosím na tento codepen https://codepen.io/a166617/pen/dyzEvMG snažil jsem se dávat to pod jedním svg značku tak, aby kód vypadá hodně tříděny a lepší, ale jsem neúspěšný. Libovolný počet iterací, aby se dal kód v jednom svg tag má za následek buď popletl s kód ještě více a někdy barchart doesnot ukázat na změny.

Může mi někdo, prosím, dejte mi vědět, jak opravit tento nepořádek, který jsem vytvořil. Bych opravdu ocenil nějaké vstupy.

Nejdůležitější nepořádek je níže uvedený kód, kde jsem měl svg pro každého jednotlivého sloupcového grafu.

{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>
))}

Zkoušel jsem reorganizaci kódu a tady je codepen za to https://codepen.io/a166617/pen/NWvZGLd

css html javascript reactjs
2021-11-24 03:25:09
1

Nejlepší odpověď

2

Snažil jsem se to udělat pomocí prostého JS. Byl schopen vytvořit jeden SVG pro graf:

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>

2021-11-24 10:45:45

Bylo to dobré cvičení ;-)
kiner_shah

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................