I am trying to add a clipping mask to set of images on SVG. But the images are not showing properly.
<g *ngFor="let node of nodeList" [attr.transform] = "'translate(0,1460) scale('+node.scalingFactor+' '+node.scalingFactor+')'" [attr.transform-origin]="''+node.x+' '+node.y+''" >
<clipPath [attr.id]="'imageclip_' + i">
<circle shape-rendering="optimizeSpeed" r="60" [attr.cx]="node.x" [attr.cy]="node.y" stroke="black" stroke-width="0" fill="black" />
</clipPath>
<image style="cursor: pointer;" [attr.clip-path]="'url(#imageclip_' + i + ')'" height = 120 [attr.x] = "node.x" [attr.y] = "node.y" transform="translate(-45 -60)" [attr.href]="node.imageUrl" />
</g>
But when I inspect on google chrome, it shows all the elements are in correct places. But the images are not displaying properly.
What can I do to display the images properly.
I found the problem after a little while. I have missed to define the i in the id of clip path. After I defined it, problem sorted. Final solution is here.
<g *ngFor="let node of nodeList; let i=index" [attr.transform] = "'translate(0,1460) scale('+node.scalingFactor+' '+node.scalingFactor+')'" [attr.transform-origin]="''+node.x+' '+node.y+''">
<clipPath [attr.id]="'imageclip_' + i">
<circle shape-rendering="optimizeSpeed" r="60" [attr.cx]="node.x" [attr.cy]="node.y" stroke="black" stroke-width="0" fill="black" />
</clipPath>
<image style="cursor: pointer;" [attr.clip-path]="'url(#imageclip_' + i + ')'" height = 120 [attr.x] = "node.x" [attr.y] = "node.y" transform="translate(-45 -60)" [attr.href]="node.imageUrl" />
</g>
Related
I would like to identify my nodes via Javascript and hence ensure that each element (graph, node, edge) has a unique ID.
I found the https://github.com/magjac/d3-graphviz#maintaining-object-constancy section and thought that.keyMode('id') would tell d3-graphviz to use my IDs. But ids are still using the graph ID and don't seem to use the node ID. I found instead a title attribute from this example: https://bl.ocks.org/magjac/28a70231e2c9dddb84b3b20f450a215f
What is this attribute? Can I be sure that it is the ID I am looking for? What is the relationship in D3-graphviz between id and title?
EDIT
I tried to dig and came up with this simple Example.
I have this (autogenerated) input file:
digraph {
label=""
id="g1"
n1 [id="n1", label="First Node"]
n2 [id="n2", label="Second Node"]
n1 -> n2 [id="e1", arrowHead="normal", arrowTail="dot"]
}
I get this outcome:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="134pt" height="116pt" viewBox="0.00 0.00 133.59 116.00">
<g id="g1" class="graph" transform="translate(4,112) scale(1)">
<polygon fill="white" stroke="transparent" points="-4,4 -4,-112 129.59,-112 129.59,4 -4,4"></polygon>
<!-- n1 -->
<g id="n1" class="node">
<title>n1</title>
<ellipse fill="none" stroke="black" cx="62.8" cy="-90" rx="52.16" ry="18"></ellipse>
<text text-anchor="middle" x="62.8" y="-85.8" font-family="Times,serif" font-size="14.00">First Node</text>
</g>
<!-- n2 -->
<g id="n2" class="node">
<title>n2</title>
<ellipse fill="none" stroke="black" cx="62.8" cy="-18" rx="62.59" ry="18"></ellipse>
<text text-anchor="middle" x="62.8" y="-13.8" font-family="Times,serif" font-size="14.00">Second Node</text>
</g>
<!-- n1->n2 -->
<g id="e1" class="edge">
<title>n1->n2</title>
<path fill="none" stroke="black" d="M62.8,-71.7C62.8,-63.98 62.8,-54.71 62.8,-46.11"></path>
<polygon fill="black" stroke="black" points="66.3,-46.1 62.8,-36.1 59.3,-46.1 66.3,-46.1"></polygon>
</g>
</g>
</svg>
but when I programmatically in an mouse event that provides me the <g> for a node, then I get the ID: svg-0.g1.n2
The last bit created the confusion. I need to find the attribute value, and not a connected value. But that will work. Thanks!
The underlying Graphviz language provides an id attribute (https://www.graphviz.org/docs/attrs/id/). Based on the d3-graphviz consistency text, it looks like d3-graphviz will honor this id attribute.
For some reason my spinner.svg is not animating when using xlink:href. Embedding the SVG on the page and using xlink:href seems to work fine, as the snippet below shows.
The problem: static (and solid!) spinner instead of animation
Why are the animation tags of the SVG suddenly not taking effect? The reference must be working since the image is actually displaying.
EDIT: Could this have to do with the shadow dom and xref?
According to Sara Soueidan "The target element must be part of the current SVG document fragment". I might be overloading what "document fragment" means, but to me document fragments belong in Shadow DOM land, and I suspect that SMIL animations might not work when using <use> statements due to this?
Working versions
.xlinked {
color: green;
}
img {
color: red; // not taking effect - of course! just a test.
}
.embedded {
color: blue;
}
<h1>xlink local</h1>
<svg class="xlinked">
<!-- could not get this external reference to work?
<use xlink:href="http://imgh.us/spinner_1.svg" />
-->
<use xlink:href="#spinner" />
</svg>
<h1>embedded</h1>
<div class="embedded">
<svg id="embedded" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round"/>
<circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round">
<animate attributeName="stroke-dashoffset" dur="2s" repeatCount="indefinite" from="0" to="502"/>
<animate attributeName="stroke-dasharray" dur="2s" repeatCount="indefinite" values="150.6 100.4;1 250;150.6 100.4"/>
</circle>
</svg>
</div>
<h1>img</h1>
<img src="http://imgh.us/spinner_1.svg" />
<h1>External absolute xlink (not working)</h1>
<svg>
<!-- could not get this external reference to work. should be the same as a local reference? -->
<use xlink:href="http://imgh.us/spinner_1.svg" />
</svg>
<h1>Source SVG with symbols for xlink reference </h1>
<svg xmlns="http://www.w3.org/2000/svg"><symbol id="spinner" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round"/><circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round"><animate attributeName="stroke-dashoffset" dur="2s" repeatCount="indefinite" from="0" to="502"/><animate attributeName="stroke-dasharray" dur="2s" repeatCount="indefinite" values="150.6 100.4;1 250;150.6 100.4"/></circle></symbol></svg>
In SVG1.1, Use element requires reference to SVG fragment not SVG URL. Try to add id attribute to root svg element of external SVG file and add hash string to href value of use element, like this.
external svg(spinner_1.svg)
<svg xmlns="http://www.w3.org/2000/svg" id="root">
<!--svg structure-->
</svg>
html uses external SVG file
<svg>
<use xlink:href="http://imgh.us/spinner_1.svg#root" />
</svg>
Note:In SVG2, you can set SVG URL to href attribute of use element. See https://www.w3.org/TR/2016/CR-SVG2-20160915/struct.html#UseElement
I have a below code,
<div id="akbar">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
width="400" height="200" viewBox="0 0 400 200">
<g transform="scale(1,-1) translate(0,-200)">
<rect x="50" y="0" fill="#f00" width="100" height="100">
<animate attributeName="height"
from="0"
to="100"
dur="0.5s"
fill="freeze" />
</rect>
<rect x="150" y="0" fill="#f70" width="100" height="200">
<animate
attributeName="height"
from="0"
to="200"
dur="0.5s"
fill="freeze" />
</rect>
<rect x="250" y="0" fill="#ec0" width="100" height="150">
<animate
attributeName="height"
from="0"
to="150"
dur="0.5s"
fill="freeze" />
</rect>
</g>
</svg>
</div>
I would like to animate the svg rectangle to grow like music waves.
How can I achieve that?
I need this behavior
You can achieve it using
values,
keyTimes
and keySplines
attributes of an <animate> tag.
JSfiddle example.
I stripped your example to single column only:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
width="400" height="200" viewBox="0 0 400 200">
<g transform="scale(1,-1) translate(0,-200)">
<rect x="50" y="0" fill="#f00" width="100" height="100">
<animate
attributeName="height"
from="0"
to="100"
dur="1s"
fill="freeze"
values="0; 200; 150; 160; 150; 160"
keyTimes="0; 0.2; 0.4; 0.6; 0.8; 1"
keySplines=".42 0 1 1;
0 0 .59 1;
.42 0 1 1;
0 0 .59 1;
.42 0 1 1;
0 0 .59 1;"
/>
</rect>
</g>
</svg>
As it is not perfect yet, you can play around with the attributes to adjust the timing better (keySplines especially) and make it more music waves like.
As you can see on the provided example, single column steps of movements are:
All the way from bottom to top
Then, from top to ~83% of height
Then, from ~83% to ~88%,
Then, from ~88% to ~83%,
Then, from ~83% to ~88%
I guess that increasing the difference between those repeating percentage numbers (83 and 88) will give you slightly better effect than mine (which is based on 75% and 80%, easier to calculate on widht: 200px), but it is close.
Also take a look at CSS tricks article on SVG animation, it is very thorough and covers all the details about mentioned attributes - and much more.
With firefox, when I middle-click (or ctrl+click) on a use element, it open the xlink:href url in new tab (like a href)
bug or feature?
<svg viewBox="0 0 400 80">
<circle id="circle" cx="40" cy="40" r="30" fill="#29e"></circle>
<use xlink:href="#circle" transform="translate(70, 0)" style="stroke: red;"></use>
</svg>
<p>ctrl+click on right circle</p>
It's an unresolved bug that they're not really sure how to handle. Trigger is the xlink:href that gets somehow internally treated just like an A.href does (middle-click or ctrl + click open to a new tab.) One workaround is to bury the xlink:href element under an invisible rect:
<svg viewBox="0 0 400 80">
<circle id="circle" cx="40" cy="40" r="30" fill="#29e" />
<use xlink:href="#circle" transform="translate(70, 0)" style="stroke: red;" />
<rect style="opacity:0" x="80" y="10" width="60" height="60" />
</svg>
<p>ctrl+click on right circle - nothing happens</p>
If you have any events that need to trigger, you'll have to tie them to the invisible rect.
As a workaround for the bug linked in previous answer you may also use pointer-events: none CSS rule on the use element:
<svg viewBox="0 0 400 80">
<circle id="circle" cx="40" cy="40" r="30" fill="#29e"></circle>
<use xlink:href="#circle" transform="translate(70, 0)" style="stroke: red; pointer-events: none;"></use>
</svg>
<p>ctrl+click on right circle</p>
Or declare that all use elements must not be clickable with <style>use{pointer-events: none;}</style>.
Obviously, this workaround is applicable only in case the element has NOT to be interactive at all.
In the following SVG document, the first rectangle's opacity is animated using calcMode=discrete, and flashes on and off as I would expect. The second rectangle is supposed to be animated using calcMode=linear, but no animation is visible in Chrome or Firefox.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 400 500">
<rect width="300" height="100" transform="translate(50,50)" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
<animate attributeName="opacity" attributeType="XML" dur="1.2s" values="0.1; 1.0; 0.1" keyTimes="0; 0.33; 0.67" calcMode="discrete" repeatCount="indefinite" />
</rect>
<rect width="300" height="100" transform="translate(50,250)" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
<animate attributeName="opacity" attributeType="XML" dur="1.2s" values="0.1; 1.0; 0.1" keyTimes="0; 0.33; 0.67" calcMode="linear" repeatCount="indefinite" />
</rect>
</svg>
http://jsfiddle.net/aJUnZ/
Is my animation not defined correctly, is this not supported by SVG, or is it simply not implemented by browsers yet?
From the SVG Specification...
For linear and spline animation, the first time value in the list must be 0, and the last time value in the list must be 1. The key time associated with each value defines when the value is set; values are interpolated between the key times.
Your final keyTimes value is not 1 and therefore your animation isn't valid. Change it to 1 and it will work.