Last active
April 17, 2018 21:58
-
-
Save petekneller/559358245e594391bc3edf9fb8bd5b16 to your computer and use it in GitHub Desktop.
SVG schematics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<title>Some experiments in how I might do multipart diagrams/schematics with SVG</title> | |
</head> | |
<body> | |
<h1>The problem</h1> | |
<p>I have a need/want to knock up schematic-like diagrams on the web with which I can: display either the whole or only parts of the diagram; zoom/scale or transform the part(s) being displayed. SVG seems to make sense a basis for this, so the question becomes one of: how do I do this with SVG?</p> | |
<h1>Solution 1: create reusable pieces of diagram which are then pulled together at the use site</h1> | |
<p>Say we have the following sub-assemblies:</p> | |
<svg xmlns="http://www.w3.org/2000/svg" height="0" width="0"> | |
<defs> | |
<circle id="aCircle" r="30" cx="30" cy="30" stroke="black" fill="yellow"/> | |
<rect id="aRect" width="120" height="10" stroke="black" fill="black" /> | |
<g id="sa1"> | |
<use href="#aCircle" /> | |
<use href="#aCircle" transform="translate(100, 0)" /> | |
<use href="#aRect" transform="translate(20, 25)" /> | |
</g> | |
<g id="sa2"> | |
<use href="#aRect" transform="translate(60, 60) rotate(45) translate(-60, -5)" /> | |
<use href="#aRect" transform="translate(60, 60) rotate(-45) translate(-60, -5)" /> | |
</g> | |
</defs> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg"> | |
<use href="#sa1" /> | |
<text x="40" y="80">Sub-assembly 1</text> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg"> | |
<use href="#sa2" /> | |
<text x="20" y="130">Sub-assembly 2</text> | |
</svg> | |
<p>As long as each of those are defined in a <def> block and given a unique id then each sub-assembly can be <use>'d independently in different scenarios. They can be rendered and manipulated alone, or they can be pulled together, like so:</p> | |
<svg xmlns="http://www.w3.org/2000/svg"> | |
<g transform="translate(0,30)"> | |
<use href="#sa1" /> | |
<use href="#sa2" transform="translate(20, -30)"/> | |
<text x="30" y="100">Whole assembly</text> | |
</g> | |
</svg> | |
<p>And of course each sub-assembly could be composed of further sub-assemblies which are composed of ... and so on to whatever level of detail is useful. However because the arranging of sub-assemblies is done at the use site I suspect that if there are a large number of <i>combinations</i> of different sub-assemblies then this will get tiresome. For example imagine you have sub-assemblies A, B and C. If you want to render A and B together you <use> them in the same diagram transforming as appropriate. Now if you want a diagram of A and C then you repeat the process, also transforming as appropriate. Now what if you want to render B and C together? There's already some A-specific transformation necessary in the first example (A + B) we've just built. And some C-specific transformation in the second example (A + C). But those must be repeated for the third, making this method very not DRY.</p> | |
<h1>Solution 2: Define a single diagram but show/hide independent sections with styling</h1> | |
<svg xmlns="http://www.w3.org/2000/svg" height="0" width="0"> | |
<defs> | |
<g id="wa" transform="translate(0,30)"> | |
<g style="visibility:var(--sa1-vis, hidden)"> | |
<use href="#aCircle" /> | |
<use href="#aCircle" transform="translate(100, 0)" /> | |
<use href="#aRect" transform="translate(20, 25)" /> | |
</g> | |
<g transform="translate(20, -30)" style="visibility:var(--sa2-vis, hidden)"> | |
<use href="#aRect" transform="translate(60, 60) rotate(45) translate(-60, -5)" /> | |
<use href="#aRect" transform="translate(60, 60) rotate(-45) translate(-60, -5)" /> | |
</g> | |
</g> | |
</defs> | |
</svg> | |
<p>An alternative is to define the whole diagram in one go (in a <defs>) but group each sub-assembly within its own <g>. Each sub-assembly can then be given a CSS visibility property based on a variable. At the use-site the diagram has only to be <use>'d as a single unit, transforming as needed. The visiblility of its sub-assemblies can be toggled on/off by setting an appropriate value for each of the CSS variales governing the individual sub-assemblies. For example, each of the below diagrams is a single <use> introducing the whole diagram but setting a different value for the variable <i>saX-vis</i>, where X is the sub-assembly.</p> | |
<svg xmlns="http://www.w3.org/2000/svg"> | |
<use href="#wa" style="--sa1-vis:visible, --sa2-vis:hidden" /> | |
<text x="30" y="130">style="--sa1-vis:visible, --sa2-vis:hidden"</text> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg"> | |
<use href="#wa" style="--sa1-vis:hidden; --sa2-vis:visible" /> | |
<text x="30" y="130">style="--sa1-vis:hidden; --sa2-vis:visible"</text> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg"> | |
<use href="#wa" style="--sa1-vis:visible; --sa2-vis:visible" /> | |
<text x="30" y="130">style="--sa1-vis:visible; --sa2-vis:visible"</text> | |
</svg> | |
<p>Or set a default value for the visibility variale and leave it off the use-site. Eg. on sub-assembly 1 is: <i>style="visibility:var(--sa1-vis, hidden)"</i> so the sub-assembly 2 diagram can become:</p> | |
<svg xmlns="http://www.w3.org/2000/svg"> | |
<use href="#wa" style="--sa2-vis:visible" /> | |
<text x="30" y="130">style="--sa2-vis:visible"</text> | |
</svg> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment