Directed graph - node level CSS styles - javascript

I found this excellent example and sample code for drawing directed graphs - http://bl.ocks.org/cjrd/6863459
However, the graph-creator.css file defines a global style for all nodes. What if I want to assign different styles to certain "special" nodes from all other nodes (I want them to be different shapes and also differently colored and if possible also a different transparency). How would I modify this code to add these node specific effects?

You can choose to append different shapes here based on different scenario:
// append new elements in <g> element in scenario X
// you can pass different parameters for specific styling here
// for example, user select "red" color rect in setting filters
newGs.append("circle")
.attr("r", String(consts.nodeRadius));
// alternatively append rect
newGs.append("rect")
.attr({
"x": // mouse event info as circles in the demo
"y": // mouse event info as circles in the demo
"width": String(consts.rectWidth),
"height": String(consts.rectHeight)
})
.attr("class", "myRectStyle") // set styles in css
.attr("fill", "red")
.attr("rx",5)
.attr("ry",5)

In order to achieve the goal, first you must understand the CSS concepts. First of all you can place a CSS for a HTML/SVG markup in 3 places.
External CSS file,
Same HTML File with a <style> block
Inline CSS inside the tag eg. <circle> <li> <line> etc.
In your case, if you want to give different styles for different nodes, then you can give them specific css class/id selectors and have styles in any of the 3 methods I have mentioned previously.
Let's say you want to make certain circles transparent, then just give the circles a class "trCircles" and specify the CSS in a external CSS file and link the file with <link>
d3.select('g')
.append('circle')
.attr('class', 'trCircle')
...
in the CSS file you can have.
.trCircle{
fill : transparent;
}
Orr if you want to apply them in the d3 level. You can specify it when you create the circle.
d3.select('g')
.append('circle')
.attr('cx' , '100')
.....
.style('fill','transparent')
;
Hope you get the idea.

Related

How to use element from defs inside a circle in D3.JS

I have a shape (a drawn cloud) in a g within a defs tag. Unfortunately, I am not able to use this shape inside a circle using d3.js. Here is my code:
JSFiddle
What I am trying to do is to display that shape which is in defs tag inside the circle shown in the SVG. I have tried many times in different ways but I could not use the shape from the defs tag inside the circle. Could anyone please assist me with this issue? Thank you in advance.
A circle can't contain other shapes. According to the MDN docs it may only contain descriptive elements and animation elements. These categories don't include shapes like circle, or use.
Rather than nesting your shapes, you should create a parent g and append the circle and use to that:
// Create a `g`, rather than a `circle`, for each data point
var groups = svg.selectAll(".group").data(data).enter().append("g")
.attr("class", "group");
// Append a `circle` to the new g
groups.append("circle")
.attr("cx",100).attr("cy",100).attr("r",20);
// Append a `use` to the new g
groups.append("use").attr("xlink:href", "#mySymbol");
JSFiddle

How to colour the links by different group in d3js

I'm trying to play with d3 network and there is an very interesting example in here. It shows the relationship between different groups by different colours. Now I'm thinking to change it by coloring the links. Ideally, I want the link color to be different by different groups. Can I achieve that by modifying the js code provided in that link?
Thanks in advance really keen to know the answer.
What about this? http://bl.ocks.org/maurizzzio/37569cdc0ed9fee40ba3
Relevant changes:
1) the stroke holds the color for a line, each link has info of the source/target nodes, to check that they belong to the same group the following check must be made: graphs.nodes[d.source].group === graphs.nodes[d.target].group but the force layout is changing the structure of graphs.links when the invoked, I could access the group using d.source.group and d.target.group, now if both groups are the same then the stroke of the line is the same as the color of source/target node
2) if not then the link is between nodes that belong to different groups, a class is added to each of these links to apply a grey stroke
.attr('stroke', function (d) {
if (d.source.group === d.target.group) {
return color(d.source.group);
} else {
d3.select(this).classed('different-groups', true);
}
})
css:
.different-groups {
stroke: #999;
}

The best way to import complex SVG graphics into D3 charts

Assume, I have some relatively complex SVG graphics as a set of files, for example, looking like these icons:
I want to use them in my D3-powered charts. So, I can go with <defs> and <use> tags and inject them as symbols. But I want to make them less solid monolithic assets, but more like fully active and editable graphic elements. I know I can manually import all paths from icons SVG code like this:
svg.append('path').attr('d', 'M7.5,5.809c-0.869,0-1.576-0.742-1.576-1.654c0-0.912,0.707-1.653,1.576-1.653 c0.87,0,1.577,0.742,1.577,1.653C9.077,5.067,8.369,5.809,7.5,5.809z')
But this doesn't seem to be a quick to run scenario as I need to build some script to convert icons to code like that or do it manually, but I want to have some simple workflow similar to just editing an icon Illustrator, saving, importing.
As a result, I want to have full control on the all the shapes and paths inside each icon.
How you think it can be done in the most straightforward and D3 way?
You can import your SVGs using d3.xml and then insert the xml directly into your document. In the example code below I create a g in a svg element and then insert an image into that:
<script>
var height = 500;
var width = 700;
var vis = d3.select("#vis").append("svg")
.attr("width", width).attr("height", height)
var g = vis.append("g").attr("id", "image");
d3.xml("drawing.svg", "image/svg+xml", function(xml) {
g.each(function() {
this.appendChild(xml.documentElement);
});
});
</script>
I guess you could also select separate icons from one SVG document containing multiple icons and insert each separately. I expect styling will be lost when the SVG document stores it's styling in a stylesheet and not directly in the elements.

d3 tooltip removes my axis (and doesn't work)

I am trying to add tooltips to my D3 graph here:
http://jsfiddle.net/ericps/b5v4R/1/
but adding these mouseevents mess up how everything is rendered and I don't know why. It is a line graph with axis
dots.enter()
.append("circle")
.attr("class", "dot")
.attr("cx", open_line.x())
.attr("cy", open_line.y())
.attr("r",3.5)
.on("mouseover", myMouseOverFunction)
.on("mouseout", myMouseOutFunction);
commenting out both .on methods at line 144 makes everything render how I expect it to
any insight into this?
The tooltips are based on this fiddle
http://jsfiddle.net/ericps/E4vrX/
You're missing myMouseOverFunction.
Simply defining the function will render your graph correctly (with the axes), allowing you to properly define your MouseOver functionality.
var myMouseOverFunction = function() {}
You can see an updated response to your jsfiddle: http://jsfiddle.net/sahhhm/hQgbc/
This could be implemented differently, but just a quick change was to remove the .FILL definition in your CSS and instead populating that value when creating the dot itself.
Few problems:
mouse:
The d3.mouse(container) function gives mouse location relative to the container (a node). You specified d3.mouse(this), but this is referring to the circle node, while you want to refer to the svg container: d3.select("svg").node().
infobox:
The infobox div was not defined anywhere, so nothing to be shown.
See updated Fiddle: http://jsfiddle.net/b5v4R/4/

javascript to change colour of an svg shape

Hi is there a way of using javascript for example using buttons to change colour of an svg shape? If so could someone please guide me in the right direction thanks
If you have a number of these shapes, then look at the d3 library, which is designed explicitly to allow you to bind data to svg attributes. A good explanation of the way it works is the Three little circles tutorial.
If you want to just change an attribute of an svg shape on a button click, then you need an onclick handler for the button:
function handleClick() {
// code to modify svg here, e.g.:
document.getElementById('svgShapeId').setAttribute('cx',150);
}
document.getElementById('buttonId').onclick = handleClick;
Here's an example of using JS to create animation elements to highlight colors based on mouse over/out:
http://phrogz.net/SVG/change-color-on-hover.svg
Here's an example of an SVG that changes lots of colors, and house some silly mouseover buttons:
http://phrogz.net/SVG/rgbhsv.svg
Here's an example that shows SVG in XHTML, with both native HTML widgets (an HTML5 slider) as well as draggable SVG elements (the path handles):
http://phrogz.net/SVG/area_of_path.xhtml
In general:
Find elements
Attach event handlers
In the event handlers, adjust properties (either via setting XML attributes or via the SVG DOM)

Categories