Issue with responsive SVG and JavaScript

Viewed 39

Still me with that SVG issues. I've made many steps further since the last time, and right now, i'm facing a new problem.

Here is the code I have so far : (Use in full screen mode)

d3.select('#step').on('click', function() {
  sections = document.getElementById("sections").value;
  deuxiemeEtape(sections);
});


//Affichage des inputs suivants
function deuxiemeEtape(sections) {

  var form = d3.select("#form2")
  form.html('');
  form.append('hr');
  form.append('p').html('Nom des sections').style('text-decoration', 'underline');
  for (i = 1; i <= parseInt(sections); i++) {
    //Ind à deux pour commencer le compteur de sous section a 2
    let ind = 2;
    const secGroup = form.append('div').attr('class', 'section');
    const sec = secGroup.append('div').attr('class', 'section-info');
    sec.append('label')
      .html("Nom de la section " + i)
      .style("text-decoration","underline")
      .attr('titreSec',(i));
    sec.append('input').attr('type', 'text')
    sec.append('button').attr('type', 'button').text('Ajouter sous section')
      .on('click', () => {
        //Insertion des sous sections supplémentaires
        const subSecGroup = subSections.append('div').attr('class', 'sous-section');
        subSecGroup.append('label').html("Nom de la sous section " + ind++);
        subSecGroup.append('input').attr('type', 'text')
        subSecGroup.append('button').attr('type', 'button')
        //Ajout de l'event pour la suppression de la sous-section
          .text('Supprimer').on('click', () => {
            subSecGroup.remove();
            //-1 à ind pour éviter d'avoir des problèmes niveau affichage du nom des sous sections
            ind--;
          })
      });

    const subSections = secGroup.append('div');
    const subSecGroup = subSections.append('div').attr('class', 'sous-section');
    subSecGroup.append('label').html("Nom de la sous section 1" );
    subSecGroup.append('input').attr('type', 'text');
  }

  //Je met les premiers input en disabled pour éviter les conflits
  // d3.select("#circles").attr('disabled', '');
  // d3.select("#sections").attr('disabled', '');
  // d3.select("#step").attr('disabled', '');
  // d3.select('select').attr('disabled','')
  form.append('button')
    .attr("id", "create")
    .html("Créer")
    .on('click', creation);
  form.append('button')
    .attr("id", "reset")
    .html("Reset")
    .on('click', reloadPage);

}
//Fonction de rechargement de page pour reset
function reloadPage() {
  window.location.reload();
}

//Fonction qui permet la création du SVG
function createSvg  (circles)  {
  const svg = d3.select('#canvas');
  const width = parseInt(svg.attr('width'));
  const height = parseInt(svg.attr('height'));
  svg.selectAll('g').remove();
  const g = svg.append('g')
    .attr('transform', `translate(${width / 2},${height / 2})`);
  const tailleChoisie=parseInt(d3.select('select').node().value);
  const epaisseur = 25 * tailleChoisie;//Changement de la taille du cercles en fonction de la taille choisie dans l'input
  const emplacementHauteur= (tailleChoisie*11)+11;//Valeur qui permet de centrer les textes peu importe la taille choisie
  const fullCircle = 2 * 3.14;

  
  const subSectionInputs = document.querySelectorAll('.sous-section input');
  const taillePetiteSection = fullCircle / subSectionInputs.length;
  const sections = document.querySelectorAll('.section');
      //Ajout des parties extérieures (Grande sections uniquement)
      let prevAngle = 0;
      for (let j = 0; j < sections.length; j++) {
        const subSections = sections[j].querySelectorAll('.sous-section input');
        const endAngle = prevAngle + (subSections.length * taillePetiteSection);
        const text = sections[j].querySelector('.section-info input').value;
        //Ajout de la section
        g.append("path")
          .attr("d", d3.arc()
            .innerRadius(circles * epaisseur)
            .outerRadius((circles + 1) * epaisseur)
            .startAngle(prevAngle)
            .endAngle(endAngle)
          )
          .attr("id", () => 'section' + circles + j)
          .attr('stroke', 'black')
          .attr('fill', colorArray[j])
          .attr('class','grande-section-'+j)
          .on('click',localisation);
        //Ajout du texte
        g.append("text")
          .attr("class", "monthText")
          .attr("dy", 22)
          .append("textPath")
          .attr("startOffset", "22%")
          .style("text-anchor", "middle")
          .attr("xlink:href", () => "#section" + circles + j)
          .text(() => text);

        prevAngle = endAngle;
      }

    

  // Ajout des parties "Intérieures" (tout ce qui n'est pas une grande section)
  for (let i = 0; i < circles; i++) {
    for (let j = 0; j < subSectionInputs.length; j++) {
      //Check si c'est une sous-section à colorer en blanc ou pas
      if (i + 1 === circles) {
        appendArcs(g, i, j, epaisseur, taillePetiteSection, colorArray[j], subSectionInputs[j].value,emplacementHauteur);
      } else {
        appendArcs(g, i, j, epaisseur, taillePetiteSection, 'white', i + 1,emplacementHauteur);
      }

    }
    
  }
  
  
}

//Fonction pour l'ajout des sections "intérieures"
function appendArcs(parent, i, j, epaisseur, arcSize, color, text,emplacementHauteur) {
  
  if(color!='white'){
    //Si c'est une sous section à color, je change la couleur. Je retire à J le nombre de sous section supplémentaire pour avoir la même couleur que la section mère
    //A CHANGER, POUR LE MOMENT JE NE TROUVE PAS COMMENT LE FAIRE
    
    color='blue'
    
  }
  //Ajout de la section
  parent
    .append("path")
    .attr("d", d3.arc()
      .innerRadius(i * epaisseur)
      .outerRadius((i + 1) * epaisseur)
      .startAngle(j * arcSize)
      .endAngle((j + 1) * arcSize)
    )
    .attr("id", () => 'section' + i + j)
    .attr('stroke', 'black')
    .attr('fill', color)
    .on('click',localisation)
    ;
    //Ajout du texte s'il y en a
  if (text) {
    parent.append("text")
      .attr("class", "monthText")
      .attr("dy", emplacementHauteur)
      .style("text-anchor", "middle")
      .append("textPath")
      .attr("startOffset", "22%")
      .attr("xlink:href", () => "#section" + i + j)
      .text(() => text);
  }

}

//Tableau de couleur pour avoir des background de section par défaut, ça évite le surplus d'inputs
var colorArray = ['#FF6633', '#FFB399', '#FF33FF', '#FFFF99', '#00B3E6', 
          '#E6B333', '#3366E6', '#999966', '#99FF99', '#B34D4D',
          '#80B300', '#809900', '#E6B3B3', '#6680B3', '#66991A', 
          '#FF99E6', '#CCFF1A', '#FF1A66', '#E6331A', '#33FFCC',
          '#66994D', '#B366CC', '#4D8000', '#B33300', '#CC80CC', 
          '#66664D', '#991AFF', '#E666FF', '#4DB3FF', '#1AB399',
          '#E666B3', '#33991A', '#CC9999', '#B3B31A', '#00E680', 
          '#4D8066', '#809980', '#E6FF80', '#1AFF33', '#999933',
          '#FF3380', '#CCCC00', '#66E64D', '#4D80CC', '#9900B3', 
          '#E64D66', '#4DB380', '#FF4D4D', '#99E6E6', '#6666FF'];


function creation() {
  const circles = d3.select('#circles').node().value;
  const sections = d3.select('#sections').node().value;
  createSvg(parseInt(circles)+1, parseInt(sections),colorArray);
}


//Fonction de localisation de la section selectionnée
function localisation(){
  console.log(event.target);
}
body{
    margin:0;
    padding:0;
    background-color: rgb(78, 98, 112);
    font-family: Helvetica;
}

input{
    border-radius: 3px;
    margin:1em 0;
}

svg{
    border:3px black solid
}

input,label{
    margin-right:1em;
}

.monthText {
    fill: #161414;
    font-size: 22px;
}
<!DOCTYPE html>
<html lang="fr">

<head>
    <meta charset="utf-8">
    <title>SVG</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
    <div>
        <div id="contenu">
            <div id="formulaire">
                <label>Nombre de cercles</label>
                <input type="number" min="1" id="circles" />
                <label>Nombre de sections</label>
                <input type="number" min="1" id="sections" />
                
                <label>Taille des cercles</label>
                <select>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                </select>
                <button id="step">Suivant</button>
            </div>
            <div id="form2">
                <!-- Insert inputs here -->
            </div>
        </div>
        <div>
            <svg id="canvas" height="750" width="1700">
                
                <text>
                </text>
            </svg>
        </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
    <script src="script.js"></script>
</body>

</html>

So as you can see, I can choose the size of the circles (3rd input) but the issue is, if the SVG generated is too big for the canvas, it just crop it. Is there a way to make the canvas bigger as the SVG is ?

For example : If the SVG generated is 800 height and 1800 width, the canvas needs to be bigger so it can show everything ? Thank you for this ! Have a great day !

0 Answers
Related