I have a list of point that represent a graph contained in a svg:group.
My html is currently:
<svg id="parent">
<g id="child">
<!-- graph list of points here -->
</g>
</svg>
Because the points are computed on user input, they can be far or not from each other but it will always be a point at the origin (0,0).
I would like to center and scale the child group in its parent in order to see all the points of the graph.
I tried to used transform on child and it center the origin point but not the whole graph.
Can someone explain me how to do? I also use d3.js to place the points.
Related
I have a stacked barchart on codepen
If you notice the x-axis of the chart, it only is available for half of the barchart. Any change i do, the line does not extend till the end of the barchart.
screenshot
This is the code which affects the x-axis line of the graph
<g class="grid y-grid" id="yGrid">
<line x1="90" x2="1505" y1="490" y2="490"></line>
</g>
I tried changing the x2 value to a higher value but no effect.
There is one more thing i am trying to achieve. Its the x coordinates and y-coordinates for the entire graph as we have in below example.
Can someone please shed some light on how to get this on the graph
I have an array of coordinates. And that coordinates occur dynamicly. So for some possibilities, it does not draw convex. Please check the example.
<div style="width : 700 , height : 700">
<svg width ="700px" height = '700px'>
<polygon points="203.21954686687195,209.09106845446956 103.21846501684684,30.73408772834725 98.7205079235916,110.89560444878055 213.4424487588524,32.1353347676166 " fill="lime" stroke="black" fillRule= 'nonzero' />
</svg>
</div>
Here is link :https://jsfiddle.net/zcj4qwpz/7/
So my question is simple : How can i make it convex for every time ? Should i generate new array for this? If so, how can i do that.
Or is there any solution by changing something on html-canvas props?
Note: I checked many questions but they didn't help me. For example this (the closest question to mine):
How to determine if a list of polygon points are in clockwise order?
Yet another question about adding labels to a d3 force graph...
I am labeling a graph with nodes that are inside individual groups, and I have been appending the labels inside these groups like so:
<svg>
<g class="nodes-with-labels">
<g class="individual-node">
<circle></circle>
<text>Node Label</text>
</g>
...
</g>
</svg>
This adds minimal extra elements to the graph and allows my graph's tick() function to just call one transform operation. I put up a demo fiddle here (without any movement/tick() function):
https://jsfiddle.net/52cLjxt4/1/
Unfortunately, the labels end up behind many of the nodes because they are in groups that are drawn before other groups that contain nodes. This problem can be solved by putting nodes and labels into separate parent groups, like in this example:
https://jsfiddle.net/hhwawm84/1/
<svg>
<g class="nodes">
<g class="individual-node">
<circle></circle>
</g>
...
</g>
<g class="labels">
<g class="individual-label">
<text>Node Label</text>
</g>
...
</g>
</svg>
However, this appears to be significantly slower: it creates more elements and requires two transform statements instead of one in the tick() statement, since it's moving the labels around separately.
Speed is a real concern for my project. Is there a better approach here that might avoid creating so many extra groups and doubling the transform statements?
You don't need to each label and circle in an g - just set the transform attribute directly on each element. It might also be worth profiling setting the cx/cy and x/y attributes instead of transform too.
If you don't need the graph to animate, precomputing the ticks and setting the transforms could help with performance:
for (var i = 0; i < 120; ++i) simulation.tick();
If that's still too slow, try using canvas (faster because it doesn't have a scene graph) or css transforms on html elements (faster because they are gpu accelerated).
I have some circles made in d3. I need to add more circles when these circles are clicked and make the existing circles disappear(they should not be removed as I will use them again).
The way I'm doing this right now is through a listener to a click event on the original circles. (these are created with .selectAll('circle.nodes')
.on("click",function(d){
//do stuff}).duration(1000);
populateSubCircles);
I want the sub circles to appear around a center (I looked at my calculations and they seem to be correct).
var populateSubCircles = function(){
var subCircles = nodesG.selectAll("circles.subNodes").data(....
This correctly adds the secondary circles, and cx and cy seem to be correct(not too far off from the center circle). However, they don't seem to appear on the page(they appear at the top left at 0,0). Why is that happening? How do I fix that?
Thanks.
EDIT-
A picture or two may help.
It's likely that you don't have the radius set on the circles (it must be set explicitly on the circle element, and cannot be set via CSS, as only style properties such as fill, stroke, etc., can be set) .
As you can see, one svg circle shows normally when set with a radius (r) of 25, and the other does not, and its size is correctly reported as 0px x 0px. (The tooltip reports size, not position). Here's the SVG I used:
<svg>
<circle cx="100" cy="100" fill="#ffdf00"
stroke="#222222" stroke-width="2px" />
<circle cx="50" cy="50" fill="#ffdf00" r="25"
stroke="#222222" stroke-width="2px" />
</svg>
This image shows the second of two circles, using inspector in Chrome web tools, it correctly reports the size:
Again, using inspector in Chrome, highlighted the first SVG element where no radius was set:
It shows the size as 0px x 0px and shows the circle as if it were in the upper left corner of the SVG document.
http://jsfiddle.net/wiredprairie/gNrZ3/
I have built a d3 force directed graph with grouped nodes. I want to enclose the groups inside cloud like structure. How can I do this?
Js Fiddle link for the graph: http://jsfiddle.net/Cfq9J/5/
My result should look similar to this image:
This is a tricky problem, and I'm not wholly sure you can do it in a performative way. You can see my static implementation here: http://jsfiddle.net/nrabinowitz/yPfJH/
and the dynamic implementation here, though it's quite slow and jittery: http://jsfiddle.net/nrabinowitz/9a7yy/
Notes on the implementation:
This works by masking each circle with all of the other circles in its group. You might be able to speed this up with collision detection.
Because each circle is both rendered and used as a mask, there's heavy use of use elements to reference the circle for each node. The actual circle is defined in a def element, a non-rendered definition for reuse. When this is run, each node will be rendered like this:
<g class="node">
<defs>
<circle id="circlelanguages" r="46" transform="translate(388,458)" />
</defs>
<mask id="masklanguages">
<!-- show the circle itself, as a base -->
<use xlink:href="#circlelanguages"
fill="white"
stroke-width="2"
stroke="white"></use>
<!-- now hide all the other circles in the group -->
<use class="other" xlink:href="#circleenglish" fill="black"></use>
<use class="other" xlink:href="#circlereligion" fill="black">
<!-- ... -->
</mask>
<!-- now render the circle, with its custom mask -->
<use xlink:href="#circlelanguages"
mask="url(#masklanguages)"
style="fill: #ffffff; stroke: #1f77b4; " />
</g>
I put node circles, links, and text each in a different g container, to layer them appropriately.
You'd be better off including a data variable in your node data, rather than font size - I had to convert the fontSize property to an integer to use it for the circle radius. Even then, because the width of the text isn't tied to the data value, you'll get some text that's bigger than the circle beneath it.
Not sure why the circle for the first node isn't placed correctly in the static version - it works in the dynamic one. Mystery.