Así que he estado trabajando en este código y lo he puesto a trabajar. Mi problema es que funciona perfectamente para la primera entrada, pero si el usuario sigue ingresando entradas, la nueva imagen se superpone a la anterior. He codificado con éxito la capacidad de reemplazar la elipse cuando se da una nueva entrada, pero tengo problemas para hacer lo mismo con todos mis elementos de ruta y marcador. Todo mi código está debajo (separado en sus archivos individuales), ¿qué debo agregar para reemplazar la imagen anterior por la nueva?

Main.js

function eccentricityChanged(){

  let svg = document.getElementById('diagram');

  let temp = document.getElementById('mytext');
  if (temp) {
    temp.remove();
  }

  let s = 100;
  let omega = 0.5;
  let A = 0.2084558583;
  let B = 0.7915441417;

  let e = document.getElementById('eccentricity').value;
  let formFactor = A * e + B;
  let eccent = Math.sqrt(Math.pow(e, 2)/(1-Math.pow(e,2)));
  let p = (1 + 1/(Math.pow(eccent, 2)))*(1-(1/eccent)*Math.atan(eccent))-(1/3);
  let q = (1/eccent)*(1+3/(Math.pow(eccent, 2)))*Math.atan(eccent)-3/(Math.pow(eccent, 2));
  let omegaStable = Math.sqrt((15/4)*q*(1-(3/5)*formFactor));
  let apperantGravA = Math.pow(1-Math.pow(e,2), -1/6)*(1-(1+p/q)*Math.pow(omegaStable, 2));
  let apperantGravB = Math.pow(1-Math.pow(e,2),1/3)*(1+2*p/q*Math.pow(omegaStable,2));
  let a = Math.pow((1-Math.pow(e,2)),-1/6);
  let b = Math.pow((1-Math.pow(e,2)),1/3);
  let scaleFactor = 150;
  let eqRad = a*scaleFactor;
  let polRad = b*scaleFactor;

  let latitude = [Math.PI/6, Math.PI/4, Math.PI/3];
  let latitudeLength = latitude.length;
  var i;

  for (i of latitude) {
    let rho = (a*Math.cos(i))/Math.sqrt(1-Math.pow(e*Math.sin(i),2));
    let z = -(a*(1-Math.pow(e,2))*Math.sin(i))/Math.sqrt(1-Math.pow(e*Math.sin(i),2));
    let lattGrav = (a* apperantGravA*Math.pow(Math.cos(i),2)+b*apperantGravB*Math.pow(
        Math.sin(i),2))/Math.sqrt(Math.pow(a*Math.cos(i),2)+Math.pow(b*Math.sin(i),2));
    let gravRho =-lattGrav*Math.cos(i)-Math.pow(omegaStable,2)*rho;
    let gravZ = -lattGrav*Math.sin(i);
    let accelCent = Math.pow(omega,2)*rho;
    calculateValues(rho, z, lattGrav, gravRho, gravZ, accelCent, polRad,s);
  }

  makeEllipse(eqRad,polRad);

}

function makeEllipse(eqRad,polRad) {
  let svg = document.getElementById('diagram');

  let temp = document.getElementById('mydiagram');
  if (temp) {
    temp.remove();
  }
  let ellipse = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  ellipse.setAttribute('d', `M 400 100 a ${polRad},${eqRad} 90 1,0 1,0 z`);
  ellipse.style.fill = 'transparent';
  ellipse.style.stroke = 'black';
  ellipse.style.strokeWidth = '5px';
  ellipse.setAttribute('id', 'mydiagram');
  svg.appendChild(ellipse);
}

function calculateValues(rho, z, lattGrav, gravRho, gravZ, accelCent, polRad,s) {
  let rho1 = rho*150 + 400;
  let z1 = z*150 + 100 + polRad;

  let rho2 = rho1 + s*gravRho;
  let z2 = z1- s*gravZ

  let rho3 = rho2 + s*accelCent;
  console.log(rho1, rho2, rho3, z1,z2);

  gravityVector(rho1, z1, rho2, z2, rho3, gravRho, gravZ, s, polRad);
  accelCentVector(rho1, z1, rho2, z2, rho3, gravRho, gravZ, s, polRad);
  apperantGravVector(rho1, z1, rho2, z2, rho3, gravRho, gravZ, s, polRad);
}

Vectors.js

function gravityVector(rho1, z1, rho2, z2, rho3, gravRho, gravZ, s, polRad) {
    let svg = document.getElementById('diagram');

    let marker= document.createElementNS('http://www.w3.org/2000/svg',
        'marker');
    marker.setAttribute('id', 'triangle');
    marker.setAttribute('viewBox', '0 0 10 10');
    marker.setAttribute('refX', '0');
    marker.setAttribute('refY', '5');
    marker.setAttribute('markerUnits', 'strokeWidth');
    marker.setAttribute('markerWidth', '10');
    marker.setAttribute('markerHeight', '8');
    marker.setAttribute('orient', 'auto');

    let path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    path.setAttribute('d', `M ${rho2} ${z2} l 5 0 l -5 10 l -5 -10 z`);
    path.style.stroke = 'green';
    path.style.strokeWidth = '5px';
    svg.appendChild(path);

    let arrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    arrow.setAttribute('d', `M ${rho1},${z1} L ${rho2} ${z2}`);
    arrow.setAttribute('id', 'gravPath')
    arrow.style.stroke = 'black';
    arrow.style.strokeWidth = '2px';
    svg.appendChild(arrow);
    arrow.setAttributeNS('marker-end', 'triangle', 'void');
}

function accelCentVector(rho, z, rho2, z2, rho3, gravRho, gravZ, s, polRad) {
    let svg = document.getElementById('diagram');

    let marker= document.createElementNS('http://www.w3.org/2000/svg',
        'marker');
    marker.setAttribute('id', 'triangle');
    marker.setAttribute('viewBox', '0 0 10 10');
    marker.setAttribute('refX', '0');
    marker.setAttribute('refY', '5');
    marker.setAttribute('markerUnits', 'strokeWidth');
    marker.setAttribute('markerWidth', '10');
    marker.setAttribute('markerHeight', '8');
    marker.setAttribute('orient', 'auto');

    let path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    path.setAttribute('d', `M ${rho3} ${z2} l 5 0 l -5 10 l -5 -10 z`);
    path.style.stroke = 'black';
    path.style.strokeWidth = '5px';
    svg.appendChild(path);

    let arrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    arrow.setAttribute('d', `M ${rho2},${z2} L ${rho3} ${z2}`);
    arrow.setAttribute('id', 'accelCentPath');
    arrow.style.stroke = 'red';
    arrow.style.strokeWidth = '2px';
    svg.appendChild(arrow);
    arrow.setAttributeNS('marker-end', 'triangle', 'void');
}

function apperantGravVector(rho, z, rho2, z2, rho3, gravRho, gravZ, s, polRad) {
    let svg = document.getElementById('diagram');

    let marker= document.createElementNS('http://www.w3.org/2000/svg',
        'marker');
    marker.setAttribute('id', 'triangle');
    marker.setAttribute('viewBox', '0 0 10 10');
    marker.setAttribute('refX', '0');
    marker.setAttribute('refY', '5');
    marker.setAttribute('markerUnits', 'strokeWidth');
    marker.setAttribute('markerWidth', '10');
    marker.setAttribute('markerHeight', '8');
    marker.setAttribute('orient', 'auto');

    let path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    path.setAttribute('d', `M ${rho3} ${z2} l 5 0 l -5 10 l -5 -10 z`);
    path.style.stroke = 'black';
    path.style.strokeWidth = '5px';
    svg.appendChild(path);

    let arrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    arrow.setAttribute('d', `M ${rho},${z} L ${rho3} ${z2}`);
    arrow.style.stroke = 'blue';
    arrow.style.strokeWidth = '2px';
    svg.appendChild(arrow);
    arrow.setAttributeNS('marker-end', 'triangle', 'void');
}

Index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>CS 5890</title>
        <script src="https://d3js.org/d3.v5.min.js"></script>
        <style>
          rect {
            fill: #9f009f;
            stroke-width: 0;
          }
          polyline {
            stroke: #00ff00;
            fill: none;
            stroke-width: 3;
          }
          line {
            stroke: #00ff00;
            fill: none;
            stroke-width: 3;
          }
          path {
            stroke: #0000ff;
            fill: #0000ff;
            stroke-width: 0;
          }
          circle {
            stroke-width: 0;
            fill: #009900;
          }
          text {
            font-size: 18px;
          }
        </style>
    </head>
    <body id="body">
      Eccentricity: <input id="eccentricity" onchange="eccentricityChanged()"></input>
      <p>Enter a value between 0 and 1 for the Eccentricity</p>

      <br>
      <svg width="800" height="800" id="diagram">
      </svg>
      <g id="diagram-elements">
          <path id =''>
      </g>
      <script src="Vectors.js"></script>
      <script src="main.js"></script>
    </body>
</html>
0
Paankey56 21 dic. 2019 a las 20:35

2 respuestas

Debe eliminar todos los elementos secundarios de su elemento svg, esta pregunta ya ha sido respondida aquí: Eliminar todos los elementos secundarios de un nodo DOM en JavaScript

En su caso, debe actualizar su función eccentricityChanged():

function eccentricityChanged(){
  let svg = document.getElementById('diagram');
  // remove all child nodes of the svg element
  while (svg.firstChild !== null) {
    svg.removeChild(svg.firstChild);
  }
  // ...
}
0
Dimitri L. 21 dic. 2019 a las 20:09

Generalmente uso un elemento contenedor ({{X0 }}) (o varios) para este tipo de operación. Algunas ventajas de usar un contenedor son que puede rotar, ocultar, escalar, mover y transformar el contenedor, y todos sus elementos secundarios rotarán, ocultarán, escalarán, moverán y transformarán con él. Además, esto debería ser más rápido que recorrer a los niños, eliminando cada uno individualmente.

En su rutina, querrá eliminar el elemento contenedor, si existe, agréguelo y agregue a todos sus hijos. La próxima vez que se ejecute su rutina, eliminará y volverá a crear el elemento contenedor, luego le agregará los elementos secundarios, etc.

Dado su código, agregaría algo como lo siguiente en la línea 9 de eccentricityChanged en main.js:

  temp = document.getElementById("container");
  if (temp) {
    temp.remove();
  }
  let container = document.createElementNS("http://www.w3.org/2000/svg", "g");
  container.setAttribute("id", "container");
  svg.appendChild(container);

Luego, en Vectors.js, agregaría cada elemento que cree a este elemento contenedor, en lugar de al documento svg externo, por ejemplo:

  let container = document.getElementById("container");

  // ...

  container.appendChild(path);

Aquí hay un ejemplo de trabajo completo.

2
tex 21 dic. 2019 a las 23:06