kristheman
kristheman

Reputation: 67

Manipulating visibility of SVG elements

I'm making a Java web project, where I want to manipulate some front-end SVG-elements with some javascript.

I'm making a fairly simple drawing of a garage, where I have a shed element coming from a JSP page.

I would like a javascript function, on/off button, where the element can be displayed and not hidden.

Here is my code so far:

....
<line x1="<%= Math.abs(wid+20) %>"  y1="0" x2="<%= Math.abs(wid+20) %>" y2="<%= len %>"
style="stroke:#c40d0d;
marker-start: url(#beginArrow);
marker-end: url(#endArrow);"/>  


//this is the start of the part that I want to be toggled on and off with a javascript function
<% if(shed){ %>

<rect x="<%= Math.abs(wid-200) %>" y="0" height="<%= len %>" width="200"
    style="stroke:#000000; stroke-width: 3; fill: none"/>


<rect x="<%= Math.abs(wid-200) %>" y="0" height="10" width="10"
    style="stroke:#000000; fill: #101111"/>
<rect x="<%= Math.abs(wid-10) %>" y="0" height="10" width="10"
    style="stroke:#000000; fill: #101111"/>
<rect x="<%= Math.abs(wid-200) %>" y="<%= Math.abs(len-10) %>" height="10" width="10"
    style="stroke:#000000; fill: #101111"/>
<rect x="<%= Math.abs(wid-10) %>" y="<%= Math.abs(len-10) %>" height="10" width="10"
    style="stroke:#000000; fill: #101111"/>

 <text x="<%= Math.abs((wid-200)+(wid/8)) %>" y="<%= Math.abs(len+35) %>" fill="Red"> Skur: 200.0 cm </text>

<line x1="<%= Math.abs(wid-200) %>"  y1="<%= Math.abs(len+20) %>" x2=" 
<%= wid %>" y2="<%= Math.abs(len+20) %>" 
style="stroke:#c40d0d;
marker-start: url(#beginArrow);
    marker-end: url(#endArrow);"/>  

<% } %>

</SVG>
<form action="FrontController?command=DynamicCarportSide" name="order" method="POST">
    <input type="hidden" name="length" value="<%= len %>">
    <input type="hidden" name="width" value="<%= wid %>">
    <input type="hidden" name="shed" value="<%= shed %>">
    <input type="submit" value="Side tegning">
</form>
      <%@include file="footer.jsp" %>
</body>
</html>

I'm using an if Statement to show with or without shed in my jsp, but can a click button be used for displaying it after the page is rendered

I was thinking of something like this.

function myFunction() {

var SVGcode ="//insert html code here";

document.getElementById("demo").innerHTML = SVGcode;
}

the problem is that the SVG-code is too much, so I don't know what to do here

EDIT:

here is a picture of how it is desired to look, so far I just have a function that writes Hello, when the button is pressed, but I desired to have a toggle-on button, that adds the additional SVG-code

Here is an example of an SVG-drawing without the dynamic data, only dummy data

Upvotes: 1

Views: 1439

Answers (1)

Ivan
Ivan

Reputation: 40618

Toggle visibility of a given element

You would like to have a function to hide and display some parts of a SVG element. The method I use actually work for any given HTML element (of object HTMLElement). You need to:

  1. give the elements you would like to hide/display a class name, for instance:

    <line class="segments" x1="55" y1="55" ... stroke-dasharray: 10 5"/>
    <line class="segments" x1="550" y1="55" ... stroke-dasharray: 10 5"/>
    
  2. write a function to toggle the visibility of a given element:

    • we will create a function hide() to hide an HTMLElement

      const hide = e => e.style.display = 'none'
      
    • and a show() function to show it...

      const show = e => e.style.display = ''
      
    • finally, the function to handle the toggle:

      const toggleHide = function(selector) {
        [...document.querySelectorAll(selector)].forEach(e => e.style.display ? show(e) : hide(e))
      }
      
  3. Lastly a trigger to call the function, we can use a button:

    <button onclick="toggleHide('.frame')">Toggle frame</button>
    

    Set the function to call in the onclick attribute of the button and give it as argument the selector (here .frame) of the element you want to link it to. I.E. this button will toggle the visibility of all elements with the class name .frame.


Demo with your svg drawing

In the demo below, I have added two buttons linked to two groups of svg elements. Click Show code snippet > Run code snippet > Full page to preview:

const hide = e => e.style.display = 'none'
const show = e => e.style.display = ''
const toggleHide = function(selector) {
  [...document.querySelectorAll(selector)].forEach(e => e.style.display ? show(e) : hide(e))
}
<html>

<body>
  <SVG width="780" height="600">
<rect x="0" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="55" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="110" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="165" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="220" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="275" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="330" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="385" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="440" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="495" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="550" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="605" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="660" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="715" y="0" height="600" width="55"
        style="stroke:#000000; fill: #ffffff"/>
<rect x="770" y="0" height="600" width="55"
        style="stroke:#000000; fill: none"/>
<rect x="0" y="50" height="15" width="825"
        style="stroke:#000000; fill: none"/>
<rect x="0" y="535" height="15" width="825"
        style="stroke:#000000; fill: none"/>

<rect class="frame" x="550" y="50" height="500" width="230"
        style="stroke:#000000; stroke-width: 5; fill: none"/>
<rect x="440" y="0" height="600" width="1"
        style="stroke:#000000; stroke-width: 3; fill: none"/>

<rect x="550" y="50" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="550" y="535" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="765" y="50" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="765" y="535" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="550" y="300" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="765" y="300" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="110" y="50" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="110" y="535" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="408" y="50" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
<rect x="408" y="535" height="15" width="15"
        style="stroke:#000000; fill: #101111"/>
  <line class="segments" x1="55" y1="55" x2="550" y2="550"
      style="stroke: #000000; fill:none;
      stroke-width: 6px;
      stroke-dasharray: 10 5"/>
  <line class="segments" x1="550" y1="55" x2="55" y2="550"
      style="stroke: #000000; fill:none;
      stroke-width: 6px;
      stroke-dasharray: 10 5"/>
  
  <text x="400" y="620" fill="Red">7,8 m</text>
  <text x="835" y="300" fill="Red">6 m</text>
  
  <defs>
    <marker id="beginArrow" 
    	markerWidth="9" markerHeight="9" 
    	refX="0" refY="4" 
    	orient="auto">
        <path d="M0,4 L8,0 L8,8 L0,4" style="fill: #c40d0d;" />
    </marker>
    <marker id="endArrow" 
    	markerWidth="9" markerHeight="9" 
    	refX="8" refY="4" 
    	orient="auto">
        <path d="M0,0 L8,4 L0,8 L0,0" style="fill: #c40d0d;" />
    </marker>
</defs>
<line x1="0"  y1="630" x2="825"   y2="630" 
	style="stroke:#c40d0d;
	marker-start: url(#beginArrow);
   marker-end: url(#endArrow);"/>
<defs>
    <marker id="beginArrow2" 
    	markerWidth="9" markerHeight="9" 
    	refX="0" refY="4" 
    	orient="auto">
        <path d="M0,4 L8,0 L8,8 L0,4" style="fill: #c40d0d;" />
    </marker>
    <marker id="endArrow2" 
    	markerWidth="9" markerHeight="9" 
    	refX="8" refY="4" 
    	orient="auto">
        <path d="M0,0 L8,4 L0,8 L0,0" style="fill: #c40d0d;" />
    </marker>
</defs>
<line x1="865"  y1="0" x2="865"   y2="600" 
	style="stroke:#c40d0d;
	marker-start: url(#beginArrow);
   marker-end: url(#endArrow);"/>
   
    
</SVG>

  <p>click on the buttons to remove some parts of the shed</p>

  <button onclick="toggleHide('.segments')">Toggle bars</button>
  <button onclick="toggleHide('.frame')">Toggle frame</button>

</body>

</html>

Upvotes: 2

Related Questions