Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
228 views
in Technique[技术] by (71.8m points)

html - techniques for dealing with large svg images

I want to let the svg expand out fully beyond the viewport so none of the shapes are squashed together. I'll then add panning and zooming which I know how to do.

But how can I let the svg expand out fully so none of the shapes are squashed together and the text labels all display their text without overlapping each other?

With my example, the svg is still trying to fit all its content into the svg viewport. I want to to let it expand outside of the viewport so nothing overlaps and use zoom and pan to view the image.

These large images are the exception and not the norm.

I've created this jsfiddle that illustrates the problem.

At the moment my viewBox is set to:

<svg opacity="1" preserveAspectRatio="xMinYMin meet" viewBox="0 0 817 664" style="opacity: 1;">
  <!-- child nodes -->
</svg>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think this is more than anything a design problem. One alternative solution to what you have would be to use some method to change the viewBox of your SVG and rotate the text to avoid overlapping, more or less like this. In this case I'm using an input type range to change the viewBox but you may decide to choose a different solution.

const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";

let A = -1200;
let B = 1200;

let hexArray = []

function drawHexagon(r){  
  let points = "";
   for( let i = 1; i <= 6; i++ ){
        let a = i * ( Math.PI / 3 );
        let x = (r * Math.cos( a - Math.PI/2 )).toFixed(3);
        let y = (r * Math.sin( a  - Math.PI/2)).toFixed(3);
        points += `${x},${y} `;
      }
  return points;
}

function useHex(theParent,pos){
   let use = document.createElementNS(SVG_NS, 'use');
   use.setAttributeNS(SVG_XLINK, 'xlink:href', '#theHex');
   use.setAttributeNS(null,"x",pos.x);
   use.setAttributeNS(null,"y",pos.y);
   //use.setAttribute("title",'x value:'+pos.x);
   theParent.appendChild(use);
   hexArray.push(use);
  
   drawText('x value:'+pos.x,pos)
}

function drawText(val,pos){
  let txt = document.createElementNS(SVG_NS, 'text');
  txt.setAttributeNS(null,"x",pos.x);
  txt.setAttributeNS(null,"y",pos.y);
  txt.textContent = val;
  txt.setAttributeNS(null,"transform",`translate(0,30) rotate(-75  ${pos.x},${pos.y})`);
  textParent.appendChild(txt);
}

function connector(parent,p){
  let path = document.createElementNS(SVG_NS, 'path');
  let d =`M${p.x},${p.y}C${p.x},125 0,125 0,0`;
  path.setAttributeNS(null,"d",d);
  parent.appendChild(path);
}

for(let x = A; x <= B; x+=50){
  let pos = {x:x,y:250}
  useHex(useParent,pos);
  connector(connectors,pos);
}



itr.addEventListener("input",()=>{
svg.setAttributeNS(null, "viewBox", `${itr.value} -50 1200 550`); 
});
svg {
  border: 1px solid;
}
use {
  fill: white;
  stroke: #000;
}

#itr {
  width: 500px;
  display: block;
  margin: 2em auto;
}

#connectors path {
  fill: none;
  stroke: black;
}

#tooltip {
  position: absolute;
}

text {
  dominant-baseline: middle;
  text-anchor: end;
}
<input id="itr" type="range" min = "-1225" max = "25" value = "-600" />

<svg id="svg" viewBox="-600 -50 1200 550" style="--display:block;">
<defs><polygon  id="theHex"  points="21.651,-12.500 21.651,12.500 0.000,25.000 -21.651,12.500 -21.651,-12.500 -0.000,-25.000 "  ></polygon>
</defs> 
<g id="connectors">
  
</g>
<g id="useParent">
<use xlink:href="#theHex" y="0"  />
</g>
<g id="textParent">
  
</g>
</svg>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...