I am using Chartist.js for some charts and I need to target some elements inside the chart in order to generate some elements that are related to them. Is there a way to target such deeply nested child elements inside the "chart1". I need to target the "g" elements with the classes of "ct-series-a", "ct-series-b", etc... But since there are multiple charts on the page that ALSO have elements with these class names, I need to only target the ones that are contained in the chart with the id of "chart1".
HTML Mock-up
<div id="chart1" class="ct-chart">
<svg>
<g>
<g class="ct-series ct-series-a"></g>
<g class="ct-series ct-series-b"></g>
<g class="ct-series ct-series-c"></g>
</g>
</svg>
</div>
Somthing like this should help you.
const chart1 = document.getElementById("chart1");
const seriesA = chart1.getElementsByClassName("ct-series-a")[0]
console.log(seriesA.className)
// I did use className , for reducing console data to show u the result in console .
<div id="chart1" class="ct-chart">
<svg>
<g>
<g class="ct-series ct-series-a"></g>
<g class="ct-series ct-series-b"></g>
<g class="ct-series ct-series-c"></g>
</g>
</svg>
</div>
Related
Using either d3.js or a javascript method, is there a way to draw the nested circle (#snap-points) on top of the line group?
<g id='panel-group'>
<rect id='panel-rectangles' />
<circle id='snap-points' />
</g>
<g id='line-group>
<line/>
</g>
document.getElementById('snap-points').appendChild(document.getElementById('line-group'))
Should do it i.e. reparent the snap-points element as a child of the line-group.
Main Question:
Is there a way to set a static width and height on <g> elements so that they don't get effected by transform attribute done on its parent view-box <svg> element?
i.e.
<svg id="viewbox" transform="translate(1,5)scale(2)">
// continuously gets the transform attr via js upon zoom event
<g>
<path "the shape of a triangle"/>
<path same/>
<path same/>
<path same/>
<path same/>
</g>
</svg>
I want everything under the <g> element to translate according to the zoom event transform values that the <svg> view-box receives, but not scale the dimensions of the <g> element. So that it looks like the screen is zooming into one section of the view-box, but without the <g> elements changing dimensions.
Instead of applying transformations to the svg element tag (svg) directly, you can use a group tag (g) to translate everything and a rectangle tag (rect) to scale only your 'viewbox'.
<svg width="1000" height="1000" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(1, 5)">
<rect
id="viewbox"
fill="black"
width="100"
height="100"
transform="scale(2)" />
<!-- your elements down here -->
<rect
fill="grey"
width="20"
height="20"
x="10"
y="10" />
</g>
</svg>
Hope this help :)
For example if i have this
<div>
<g class="one"></g>
<g class="two"></g>
<g class="three"></g>
<g class="four"></g>
<g class="five"></g>
</div>
If i want to insert another g with class new in between the the two g with class three and two.
Resulting in
<div>
<g class="one"></g>
<g class="two"></g>
<g class="new"></g>
<g class="three"></g>
<g class="four"></g>
<g class="five"></g>
</div>
These work:
d3.select("div").insert("g", ".three").attr("class", "new");
d3.select("div").insert("g", ":nth-child(3)").attr("class", "new");
But it will not work if i have this and want to insert a g with class new at where the line is. (I've used lines as I'm not sure if i will explain it correctly)
<div>
<g class="one">
<g class="two">
<circle></circle>
</g>
<g class="one">
<circle></circle>
</g>
<g class="one">
<circle></circle>
</g>
</g>
<g class="one"></g>
------------------(this is where i want <g class="new"></g>)--------
<g class="two"></g>
<g class="one"></g>
<g class="one"></g>
</div>
Is it possible to insert it by only counting the number of g at the level under div. E.g between the 2nd and 3rd g tag.
I've tried something like:
d3.select("div").insert("g", "div > g, g:nth-of-type(3)").attr("class", "new");
I figured out a workaround:
d3.selectAll("g").filter("div > g").classed("temp", true);
d3.select("div").insert("g", ".temp:nth-of-type(3)").attr("class", "new");
d3.selectAll(".temp").classed("temp", false);
But it seems really inefficient.
The following should work for you:
d3.select("div").insert("g", ".three").attr("class", "new");
Here's a working fiddle.
If you wanted to insert after the nth element, rather than after a specific class, you can do something like:
d3.select("div").insert("g", ":nth-child(3)").attr("class", "new");
If you need even more flexibility (maybe you have other elements in that div other than g), you can insert before the nth g like so:
d3.select("div").insert("g", "g:nth-of-type(3)").attr("class", "new");
EDIT:
Still unclear what you're trying to accomplish, but here is my last attempt:
d3.select("div").insert("g", "div > g:nth-of-type(3)").attr("class", "new").append("text").text("new ");
Codepen
This will insert the new g before the third g element that is a direct child of the div. It has nothing to do with the classes, I don't know why you mentioned classes in the first place, especially if you knew they were not unique but your example makes it appear as if that were so.
You should read this.
I need to display use elements in my SVG graphic.
When I try to use them from within a g element it doesn't work.
In a little demo it looks like the use element works outside of g elements.
Here the fiddle (you can scroll down to the use elements to see the demo):
http://jsfiddle.net/3dacnxdb/2/
Why is it like this? How can i display them from within a g element?
(My graphic is made out of many modules I need the gs to seperate them)
I appreciate any help!
<svg id="graphic">
<defs>
<clipPath id="icon-cp">
<rect x="0" y="0" width="150" height="100" />
</clipPath>
<image id="icon-sprite" width="969" height="293"
xlink:href="http://i.stack.imgur.com/TPx5h.png" />
<g id="icon2" clip-path="url(#icon-cp)">
<use xlink:href="#icon-sprite" transform="translate(-240,0)" />
</g>
</defs>
<!-- ----------------------------------------
Here is the question:
the first use element is not displayed.
The second one is displayed. (the elements are under this text)
Why does it not work?
How can a use element be used within nested g elements?
(to test it you can comment out the second use element,
even tough both use elements have the same attributes
no icon is visible anymore)
---------------------------------------- -->
<!-- following does not work: -->
<g id="testg">
<use xlink:href="#icon2" x="100" y="50" />
</g>
<!-- following works: -->
<use xlink:href="#icon2" x="100" y="50" />
<!-- why???? -->
It does work. Your jsfiddle is not the same as your inline code (the x and y of the use are not the same).
If you make the x and y values in the <g> the same as outside it will work. In the non-working case you are clipping out the contents of the <use> with your clip-path.
You can't see it because they are superposed... =)
<svg id="graphic">
<defs>
<clipPath id="icon-cp">
<rect x="0" y="0" width="150" height="100" />
</clipPath>
<image id="icon-sprite" width="969" height="293" xlink:href="http://i.stack.imgur.com/TPx5h.png" />
<g id="icon2" clip-path="url(#icon-cp)">
<use xlink:href="#icon-sprite" transform="translate(-240,0)" />
</g>
</defs>
<!-- ----------------------------------------
Here is the question:
the first use element is not displayed.
The second one is displayed. (the elements are under this text)
Why does it not work? How can a use element be used within nested g elements?
(to test it you can comment out the second use element, even tough both use elements have the same attributes no icon is visible anymore)
---------------------------------------- -->
<!-- following does not work: -->
<g id="testg">
<use xlink:href="#icon2" x="0" y="0" />
</g>
<!-- following works: -->
<use xlink:href="#icon2" x="100" y="50" />
<!-- why???? -->
I couldn't find the way how to embed two SVGs into SVG document. I need to do it with ability of code which would manipulate with both child SVG-s, and would like to have independent coordinates on both of those areas.
I don't like to do it in HTML, because I consider it too limiting comparing to SVG.
Many thanks!
An SVG document fragment consists of any number of SVG elements contained within an ‘svg’ element.
Source: http://www.w3.org/TR/SVG/struct.html#NewDocument
Basically:
<svg …>
<svg id="a" …>…</svg>
<svg id="b" …>…</svg>
</svg>
<svg>
...
<image x="..." y="..." width="..." height="..." xlink:href="path/to/your/file.svg" ></image>
...
</svg>
One of solution is '[parent svg] - [g] - [child svg]' structure.
<svg>
<g transform="translate(-,-)">
<svg>
...
</svg>
</g>
</svg>
You can set the cordinate of child svg as transform(translate) of g element.
demo:
http://hitokun-s.github.io/old/demo/path-between-two-svg.html