d3: draw heat map by US individual state - javascript

I'm using this GeoJSON http://eric.clst.org/wupl/Stuff/gz_2010_us_050_00_5m.json. Since it gives data about US counties, when I draw the path, the US is divided into counties. However, is there a way to only draw path by states? Then, when a user clicks on a state, the map will zoom in and show the heat map of that state.
This is what I wrote to draw path:
d3.json("http://eric.clst.org/wupl/Stuff/gz_2010_us_050_00_5m.json", function(data) {
svg.selectAll("path")
.data(data.features)
.enter()
.append("path")
.attr("d", path)
.style("stroke", "black")
.style("stroke-width", "1");
.style("fill", "orange");
});
I would really appreciate any advice. Thanks!

it seems like the geojson you have is divided by counties, the easy way to fix this is looking for a geojson of the states, in any case here is a link that may help you. And also contains a geojson of the states.
GeoMapping in D3

Related

Map didn't render in 3d.js

I have a project that is about data visualization, however I am encountering problems. I need to render a map of a country (Brazil) using d3.js. When I move the mouse through the state it should appear the acronym of the state with the income per capita. In addition each state must be in a color tint (in the case I chose green) based on per capita income. I am sending my code because I am not getting my map to render the correct colors and are not showing the acronym and the income. If anyone can help, I appreciate it.
Here´s a link of the code
I see a couple problems with the code that builds each country's path -- try updating this section:
svg.append("g")
.selectAll("path")
.data(topojson.feature(br, br.objects.states).features)
.enter().append("path")
.attr("class", "states")
.attr("fill", function(d) { return color(valueByÚF.get(d.UF)); })
.attr("d", path)
.append("title")
.text(function(d) { return "UF: "+ d.UF; });
Honestly, I didn't check to see if the quantize scale is the right one to use for your data, so you may want to try other scales...

Is there a way to add different shapes depending on different data to my force-directed graph?

I'm sure this has been covered in another question on here however, after trying many different examples on my code i cannot seem to get this to work.
I am trying to make the nodes on my force-directed graph a different shape depending on the name of the node, for example, if the node is named 'Switch' it should be displayed as a square.
I have worked out the set up for changing the colour of the nodes based on the data and would like a similar thing for the shape but can't get it to work using d3.v4.
Any help?
var color = d3.scaleOrdinal(d3.schemeCategory10);
var shape = d3.symbolTypes;
var node = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 15)
.attr("fill", function(d) { return color(d.group); })
.attr("d", d3.symbol()
.type(function (d) { return shape(d.name);}))
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
Many Thanks
Faye
You can't use:
var shape = d3.symbolTypes;
....
shape(d.name);
since d3.symbolTypes is not defined in d3 v4 (it was in some versions of v3), in v4 use d3.symbols which is an array not a function.
But, as with color, you could create an ordinal scale for shape:
var color = d3.scaleOrdinal(d3.schemeCategory20);
var shape = d3.scaleOrdinal(d3.symbols);
Now all you have to do is append that shape:
.append('path')
.attr("d", d3.symbol().type( function(d) { return shape(d[property]);} ) );
Since you were appending circles, and are now appending paths, you'll need to change .append('circle'), and as circles have cx cy elements, you need to change to a transform where you set their position.
Here is a bl.ock which should show this in practice, based on MBostock's force directed graph (here)
Keep in mind there are only seven shapes in the d3.symbols array.
Edit:
If you want to specify which shapes get displayed for each node based on a property (rather than letting the ordinal scale set the shape), you could add a property to your data which contains the name of a shape (eg: d3.symbolCross), or create a function which takes in a data value and outputs the name of a symbol. But an ordinal scale is easiest.

Confused about binding chord data to ribbon path

In referencing this chord diagram example: https://bl.ocks.org/mbostock/4062006
The following block sets up the ribbon:
var ribbon = d3.ribbon()
.radius(innerRadius);
But then later in the code ribbon is then used in a way I can't understand:
g.append("g")
.attr("class", "ribbons")
.selectAll("path")
.data(function(chords) { return chords; })
.enter().append("path")
.attr("d", ribbon)
.style("fill", function(d) { return color(d.target.index); })
.style("stroke", function(d) { return d3.rgb(color(d.target.index)).darker(); });
How is it that .attr("d", ribbon) knows how to pass in the chord data to ribbon? Is this just part of D3 magic that I have to just remember?
In your example, d3.chord() computes the layout of the data. It's important to note that, in d3, "layout" has a different meaning of layout in data visualisation: here, layout has to do with preparing the data to create a given chart (not the visual "layout" of the chart).
Basically, d3.chord() takes your data matrix and creates another data matrix with a bunch of starting angles and ending angles, associating sources to targets.
After d3.chord() modifies the data, they are passed to d3.ribbon(). d3.ribbon is the real path generator, creating the actual path that will be painted in the SVG. How does it knows the data? You have previously bounded the modified data to your group:
.datum(chord(matrix));
That's the data passed to d3.ribbon().
According to the API, d3.ribbon()...
...generates a ribbon for the given arguments. The arguments are arbitrary; they are simply propagated to the ribbon generator’s accessor functions along with the this object [...] with the default settings, a chord object expected.

D3 Sankey Chord Colors

So I'm developing a Sankey diagram, using D3's Sankey API, and I'm trying to figure out how to change the color of the bands, or cords, going to and from the nodes. An example of what I'm trying to do can be found here:
http://tamc.github.io/Sankey/
I want to be able to individually choose each band and choose that individual band's color. I can't find any documentation for D3's Sankey API so I have no idea how to actually pull this off. I tried the setColors function that I found by searching through the code of the Sankey in the link that I provided. However, that doesn't seem to work with my code. I started my Sankey off using this code as a base:
http://tamc.github.io/Sankey/examples/simple.html
Can someone please give me an idea of how to change the color of a band using this as a reference?
P.S. If someone could also fill me in on how to change the color of a node, as well, that would be great!
The example you've linked to uses a different API on top of the Sankey plugin. I'll explain for this example. The Sankey plugin doesn't draw the visual elements, it only computes their positions, so you're free to set the colors as you like.
The relevant code for the links in the example is this:
var link = svg.append("g").selectAll(".link")
.data(energy.links)
.enter().append("path")
.attr("class", "link")
.attr("d", path)
.style("stroke-width", function(d) { return Math.max(1, d.dy); })
.sort(function(a, b) { return b.dy - a.dy; });
To change the color, simply set either a different class or set stroke explicitly:
.style("stroke", "red")
This can of course be a function as well so that you can set different colors for different paths. The nodes are similar:
node.append("rect")
.attr("height", function(d) { return d.dy; })
.attr("width", sankey.nodeWidth())
.style("fill", function(d) { return d.color = color(d.name.replace(/ .*/, "")); })
.style("stroke", function(d) { return d3.rgb(d.color).darker(2); })
In the example, the fill color is set based on the name -- you can adjust this as you like.

Area fill for realtime graph

I have implemented a realtime graph with javascript and d3.js. The data is generated randomly and it changes based on the random number. I want to fill the area under the line chart but I do not know how to fill it since the data is moving! The following code are correct for static charts but how I can use it for dynamic moving data
//Css part
.area {
fill: lightsteelblue;
stroke-width: 0;
}
//script
var area = d3.svg.area()
.x(function(d, i) { return x(i); })
.y0(height)
.y1(function(d, i) { return y(d); });
svg.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
And that is how my data is generated:
var n = 100,
random = d3.random.normal(0, 50),
data = d3.range(n).map(random);
Thanks,
In order to move the area in real time, you will have to do quite a bit of work. Fortunately Mike Bostock wrote a very good tutorial for path transitions with d3.js.
The key code is:
// push a new data point onto the back
data.push(random());
// redraw the line, and then slide it to the left
path
.attr("d", area)
.attr("transform", null)
.transition()
.ease("linear")
.attr("transform", "translate(" + x(-1) + ")");
// pop the old data point off the front
data.shift();
Also note that you will certainly have to use selections at one point, to do so you can have a look at the following tutorial: A Bar Chart, Part 2.
Add to that the example of area chart that you already use and you are nearly done! The only difference is that you write
Now, you can also get inspiration from the following question: Smooth update to x axis in a D3 line chart?
Finally, here is a jsFiddle that provides you a working example of what you are looking for.

Categories