Javascript Function Ordering - javascript

I have a basic question about how javascript functions execute within HTML. I'm creating a graph with dimple.js and want to select an svg element once the graph has been created via javascript. However, even when my jQuery selector is the very last bit of script on my page, it won't execute because the dimple graph hasn't actually been created. Here's the code I'm working with:
<html>
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.0.0.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
function draw(data) {
"use strict";
var margin = 75,
width = 1400 - margin,
height = 600 - margin;
d3.select("body")
.append("h2")
.text("World Cup Attendance")
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin)
.attr("height", height + margin)
.append('g')
.attr('class','chart');
var myChart = new dimple.chart(svg, data);
var x = myChart.addTimeAxis("x", "year");
myChart.addMeasureAxis("y", "attendance");
x.dateParseFormat = "%Y";
x.tickFormat = "%Y";
x.timeInterval = 4;
myChart.addSeries(null, dimple.plot.line);
myChart.addSeries(null, dimple.plot.scatter);
myChart.draw();
};
</script>
</head>
<body>
<script type="text/javascript">
d3.tsv("world_cup.tsv", draw);
debugger
$('.example').doSomething();
</script>
</body>
</html>
I assumed the page and graph would be fully loaded where I placed the debugger statement at the bottom because that's the last line of code. However when the page pauses there the graph hasn't actually been created. After the debugger line the page runs through a bunch of functions in the dimple library to create the svg graph. Obviously the jQuery line right after doesn't work because there's no element to select yet.
I think I'm missing something fundamental when it comes to javascript. How do I get my jQuery to run only after dimple has done its thing?

You're supplying the draw function as a callback to the CSV request.
The drawing is done when draw is done. So put it there, or create a little anonymous function that calls them in sequence, e.g.,
d3.tsv("world_cup.tsv", function() {
draw();
$('.example').doSomething();
);
(If D3/Dimple's chart draw() function is also async then you'd need to do it in that callback, if it has one, but I don't know Dimple.)

Related

How to fix graph so it doesn't write over itself when resizing

I am trying to make my graph resize with the window when changed. I put my code that makes the graph in a function and added an event listener that calls the main function with updated height and width variables when added however it doesn't remove the already added in bars, lines, axes, labels, etc. causing an effect where the graph rescales properly but doesn't remove all the old stuff so I end up with hundreds of bars on my graph.
I tried just putting in a white rectangle each time the window resizes, however it takes too long for the graph to load in such a way that it flickers while resizing and doesn't look good.
Also to note: I have the function chart() run on load in my HTML file. Here is a link to what it looks like:
https://imgur.com/iuDXjpC
var margin = {top: 10, right: 70, bottom: 100, left: 70},
w = window.innerWidth,
h = window.innerHeight;
var topBottom = margin.top + margin.bottom;
var leftRight = margin.left + margin.right;
var mid = {x: w/2, y:h/2};
var svg = d3.select("#svgDiv")
.append("svg")
.attr("width",w)
.attr("height",h)
.attr("margin","auto");
function chart(){
w = window.innerWidth;
h = window.innerHeight;
d3.csv("test.csv").then(function(dataset) {
part where I make the graph
}
}
window.addEventListener("resize",chart);
Should I just remove everything and redraw it whenever 'chart()' is called? or should I better optimize my code and then just put a white rectangle over old window sizes so that the one that is desired is on top.
If you're going to use resize events, you can do two things. Either remove all children of svg before drawing (svg.selectAll("*").remove();) anything, or, if you want to optimize the code, split the loading and handling of the data and the drawing of the chart into two parts.
First, when you load the data, store it as a variable and use the .data attribute to add/remove SVG nodes based on it. For example, if you have three bars in the data, you add the rect nodes here, but don't do anything about their placement.
Then, inside the function that is also called on resize, you first take the xScale and yScale variables and call .range() with the new size. Take the variable you assigned the three rect nodes to, and set their x, y, width, and height attributes based on their values as you loaded them in the first part. Note that all these values are indirectly based on the values you passed to xScale and yScale .range() function.
I can't help you more specifically without seeing more code, so I hope this helps.

Geojson map not showing up

I'm struggling with creating a map. I am simply using one of the new york times geojsons ("census_tracts_2010.geojson") from here ( https://github.com/dwillis/nyc-maps ).
I'd appreciate it if someone could look at my code below, and let me know why no map is showing up for me, especially I have no errors. If something is wrong, then it's probably in the last two lines.
STEP 1 - CONVERT GEOJSON TO TOPOJSON
ran this in terminal
geo2topo census_tracts_2010.geojson > nyc2.json
STEP 2
created index.html
(inspired by https://bost.ocks.org/mike/map/)
<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 1160;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("nyc2.json", function(error, uk) {
if (error) return console.error(error);
console.log(uk.objects)
console.log(uk.objects.census_tracts_2010)
svg.append("path")
.datum(topojson.feature(uk, uk.objects.census_tracts_2010))
.attr("d", d3.geo.path().projection(d3.geo.albersUsa()));
});
</script>
My output:Plain white webpage
Updated code:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 500,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("census_tracts_2010.geojson", function(error, uk) {
if (error) return console.error(error);
var subunits = topojson.feature(uk, uk.objects.nyct2010);
var projection = d3.geo.albers()
.center([0,40.7])
.rotate([-74,0])
.translate([width/2,height/2])
.scale(65000);
var path = d3.geo.path()
.projection(projection);
svg.append("path")
.datum(subunits)
.attr("d", path);
});
</script>
Data Source
First, your referenced file is already a topopjson. You can contrast the differences with a regular geojson in this file (from the same repository).
The most visible difference is that geojson uses recognizable coordinates while topojson uses arcs and what might look like arbitrary coordinates. Topojsons also finish with scale and translate values.
The Problem
Why does your map not appear? Well that could be because of issues in topojsoning a file that is already a topojson, but a more likely option - and one that touches on your other question - is that you are not focusing your map on your area of interest. This appears to be the the issue in your previous question as well.
You are using a geo.albersUsa projection - this is by default focused on the entire continental US (it's a composite projection so it includes space for Alaska and Hawaii).
Changing your code only to use the topojson you reference (census_tracts_2010) I got:
Your map is displaying properly - or at least as coded - but the entire area of interest looks like it could be a small insect that hit the screen to fast.
AlbersUSA vs Albers
You will need to modify your map projection parameters but if you want to keep the AlbersUSA projection you will not be able to center or rotate, instead use a plain Albers projection. The AlbersUsa is intended for the entire country and I don't believe it has centering or rotation methods.
Setting Map Parameters
To set an Albers projection you'll want to know the center of latitude and longitude of your area of interest. Let's say about 40.7N and 74 W - I used Google Earth to generalize and then adjusted until I got a pleasant result.
Generally for an Albers you also want to know your standard parallels; however, in d3 the default parallels are for the US. Yes, they could be made more specific for your projection (by choosing two parallels that intersect the upper and lower portions of your area of interest), but I'll leave them out in this answer.
The general pattern for an Albers projection in D3 is:
var projection = d3.geo.albers()
.center([0,y])
.rotate([-x,0])
.parallels([a,b]) // don't worry about this in this instance
.translate([width/2,height/2])
.scale(k);
Using the center coordinates above and a few attempts to get the scale down I got this:
Using:
var projection = d3.geo.albers()
.center([0,40.7])
.rotate([74,0])
.translate([width/2,height/2])
.scale(65000);
Note: I've modified your svg dimensions to something more appropriate to the shape of your area of interest (as opposed to the reference map dimensions in the demonstration creating a map of the UK). My dimensions are: 500 x 500.
A relatively more detailed explanation of an Albers projection's parameters is in this answer.

JSON map too big -- how to find the right scale and projection?

I am trying to adapt Mike Bostock's map tutorial for a different map. I have this working code using the uk.json file:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/* CSS goes here. */
</style>
<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
/* JavaScript goes here. */
var width=960, height=1160;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height) ;
d3.json("./shapefiles/uk.json", function(error, uk){
if (error) return console.error(error);
svg.append("path")
.datum(topojson.feature(uk,uk.objects.subunits))
.attr("d", d3.geo.path().projection(d3.geo.mercator()));
});
</script>
But when I try to use a similar design with my new.json file all I get is a big black rectangle instead of a map.
This is how the uk.json file starts out:
{"type":"Topology","objects":{"subunits":{"type":"GeometryCollection","geometries":[{"type":"MultiPolygon","properties":{"name":"England"},"id":"ENG","arcs":[[[0]],[[1]],[[2]],[[3]],[[4]],[[5]],[[6,7,8,9]]]},{"type":"MultiPolygon","properties":{"name":"Ireland"},"id":"IRL","arcs":[[[10]],[[11]],[[12]],[[13]],[[14]],[[15]],[[16,17]]]},{"type":"MultiPolygon","properties":{"name":"N. Ireland"},"id":"NIR","arcs":[[[-17,18]],[[19]]]},{"type":"MultiPolygon","properties":{"name":"Scotland"},"id":"SCT","arcs":[[[20]],[[21]],[[22]],[[23]],[[24]],[[25]],[[26]],[[27]],[[28]],[[29]],[[30]],[[31]],[[32]],[[33]],[[34]],[[35]],[[36]],[[37]],[[38]],[[39]],[[40]],[[41]],[[42]],[[43]],[[44]],[[45]],[[46]],[[47]],[[48]],[[-9,49]],[[50]],[[51]],[[52]],[[53]],[[54]],[[55]],[[56]],[[57]],[[58]],[[59]],[[60]],[[61]],[[62]],[[63]],[[64]],[[65]],[[66]]]},{"type":"MultiPolygon","properties":{"name":"Wales"},"id":"WLS","arcs":[[[67]],[[-7,68]],[[69]]]}]},"places":{"type":"GeometryCollection","geometries":[{"type":"Point","properties":{"name":"Ros Comain"},"coordinates":[3562,3404]},{"type":"Point","properties":{"name":"Muineachan"},"coordinates":[4349,3968]},{"type":"Point","properties":{"name":"Greenock"},"coordinates":[5782,5506]},{"type":"Point","properties":{"name":"Sunderland"},"coordinates":[7961,4580]},{"type":"Point","properties":{"name":"Southampton"},"coordinates":[7948,905]},{"type":"Point","properties":{"name":"Bristol"},"coordinates":[7183,1408]},{"type":"Point","properties":{"name":"Bournemouth"},"coordinates":[7625,750]},{"type":"Point","properties":{"name":"Omagh"},"coordinates":[4133,4288]},{"type":"Point","properties":{"name":"Chester"},"coordinates":[6965,3008]},{"type":"Point","properties":{"name":"Swansea"},"coordinates":[6299,1573]},{"type":"Point","properties":{"name":"Carlisle"},"coordinates":[6959,4544]},{"type":"Point","properties":{"name":"Southend-on-Sea"},"coordinates":[9319,1500]},{"type":"Point","properties":{"name":"Reading"},"coordinates":[8220,1426]},{"type":"Point","properties":{"name":"Leicester"},"coordinates":[8121,2487]},{"type":"Point","properties":{"name":"Bradford"},"coordinates":[7722,3556]},{"type":"Point","properties":{"name":"Sheffield"},"coordinates":[7884,3160]},{"type":"Point","properties":{"name":"Shannon"},"coordinates":[3122,2554]},{"type":"Point","properties":{"name":"Waterford"},"coordinates":[4255,2147]},{"type":"Point","properties":{"name":"Tralee"},"coordinates":[2570,2155]},{"type":"Point","properties":{"name":"Donegal"},"coordinates":[3605,4333]},{"type":"Point","properties":{"name":"Fort William"},"coordinates":[5548,6314]},{"type":"Point","properties":{"name":"Ayr"},"coordinates":[5868,5065]},{"type":"Point","properties":{"name":"Aberdeen"},"coordinates":[7509,6637]},{"type":"Point","properties":{"name":"Perth"},"coordinates":[6610,5933]},{"type":"Point","properties":{"name":"Dundee"},"coordinates":[6914,5997]},{"type":"Point","properties":{"name":"Middlesbrough"},"coordinates":[8058,4270]},{"type":"Point","properties":{"name":"Coventry"},"coordinates":[7884,2295]},{"type":"Point","properties":{"name":"Bath"},"coordinates":[7334,1348]},{"type":"Point","properties":{"name":"Exeter"},"coordinates":[6571,723]},{"type":"Point","properties":{"name":"Cambridge"},"coordinates":[8929,2094]},{"type":"Point","properties":{"name":"Kingston upon Hull"},"coordinates":[8640,3511]},{"type":"Point","properties":{"name":"Londonderry"},"coordinates":[4112,4654]},{"type":"Point","properties":{"name":"Lisburn"},"coordinates":[4540,4215]},{"type":"Point","properties":{"name":"Penzance"},"coordinates":[5265,205]},{"type":"Point","properties":{"name":"York"},"coordinates":[8155,3712]},{"type":"Point","properties":{"name":"Blackpool"},"coordinates":[6881,3584]},{"type":"Point","properties":{"name":"Dumfries"},"coordinates":[6558,4715]},{"type":"Point","properties":{"name":"Scarborough"},"coordinates":[8576,3995]},{"type":"Point","properties":{"name":"Plymouth"},"coordinates":[6164,435]},{"type":"Point","properties":{"name":"Ipswich"},"coordinates":[9610,1975]},{"type":"Point","properties":{"name":"Norwich"},"coordinates":[9694,2487]},{"type":"Point","properties":{"name":"Brighton"},"coordinates":[8744,842]},{"type":"Point","properties":{"name":"Kirkwall"},"coordinates":[6946,8280]},{"type":"Point","properties":{"name":"Inverness"},"coordinates":[6116,6909]},{"type":"Point","properties":{"name":"Oxford"},"coordinates":[8045,1701]},{"type":"Point","properties":{"name":"Luton"},"coordinates":[8582,1802]},{"type":"Point","properties":{"name":"Portsmouth"},"coordinates":[8155,814]},{"type":"Point","properties":{"name":"Peterborough"},"coordinates":[8692,2441]},{"type":"Point","properties":{"name":"Nottingham"},"coordinates":[8097,2798]},{"type":"Point","properties":{"name":"Stoke"},"coordinates":[7444,2825]},{"type":"Point","properties":{"name":"Dover"},"coordinates":[9694,1119]},{"type":"Point","properties":{"name":"Drogheda"},"coordinates":[4749,3483]},{"type":"Point","properties":{"name":"Dundalk"},"coordinates":[4704,3740]},{"type":"Point","properties":{"name":"Galway"},"coordinates":[3002,3074]},{"type":"Point","properties":{"name":"Kilkenny"},"coordinates":[4164,2509]},{"type":"Point","properties":{"name":"Killarney"},"coordinates":[2700,1957]},{"type":"Point","properties":{"name":"Sligo"},"coordinates":[3368,3983]},{"type":"Point","properties":{"name":"Edinburgh"},"coordinates":[6772,5520]},{"type":"Point","properties":{"name":"Newcastle"},"coordinates":[7818,4655]},{"type":"Point","properties":{"name":"Liverpool"},"coordinates":[6965,3207]},{"type":"Point","properties":{"name":"Cardiff"},"coordinates":[6768,1454]},{"type":"Point","properties":{"name":"Wick"},"coordinates":[6860,7792]},{"type":"Point","properties":{"name":"Leeds"},"coordinates":[7831,3586]},{"type":"Point","properties":{"name":"Cork"},"coordinates":[3360,1818]},{"type":"Point","properties":{"name":"Lerwick"},"coordinates":[8110,9361]},{"type":"Point","properties":{"name":"Limerick"},"coordinates":[3277,2519]},{"type":"Point","properties":{"name":"Manchester"},"coordinates":[7399,3284]},{"type":"Point","properties":{"name":"Birmingham"},"coordinates":[7611,2347]},{"type":"Point","properties":{"name":"Belfast"},"coordinates":[5000,4288]},{"type":"Point","properties":{"name":"Glasgow"},"coordinates":[6104,5454]},{"type":"Point","properties":{"name":"Dublin"},"coordinates":[4811,3131]},{"type":"Point","properties":{"name":"London"},"coordinates":[8777,1456]}]}},"arcs":[[[4788,4],[-7,-4],[-7,4],[1,12],[5,8],[5,-3],[5,-9],[-2,-8]],[[4763,36],[-4,-7],[-6,3],[-4,11],[-1,7],[5,-1],[3,-2],[2,-1],[4,-3],[1,-7]],[[8016,789],[98,-36],[16,1],[6,-1],[8,-6],[1,-2],[-1,-8],[0,-2],[2,-1],[6,1],[1,0],[14,-19],[0,-7],[-3,0],[-2,-2],[-1,-2],[-3,-2],[-24,-7],[-10,-4],[-18,-14],[-4,-5],[-2,-4],[1,-20],[-1,-10],[-2,-5],[-72,-19],[-23,6],[-84,54],[-5,6],[-21,13],[-8,3],[-24,-2],[-11,-4],[-11,-7],[15,26],[26,20],[56,23],[-1,-3],[-2,-6],[-1,-3],[16,2],[15,11],[22,24],[16,10],[15,1]],[[8247,803],[0,-6],[-53,6],[0,7],[14,5],[17,26],[8,0],[6,-5],[2,-6],[-3,-5],[-5,-4],[0,-5],[3,-3],[6,-7],[5,-3]],[[5838,1147],[-5,-4],[-5,6],[-1,13],[3,11],[3,2],[3,-7],[1,-3],[1,-6],[0,-12]],[[9459,1336],[-16,-6],[-75,5],[-13,5],[-11,10],[-10,12],[-6,12],[9,25],[4,5],[9,2],[80,-24],[6,-4],[7,-4],[14,-14],[6,-13],[-4,-11]],[[7130,1561],[-5,19],[0,8],[-3,7],[-4,4],[0,3],[2,2],[10,4],[2,3],[0,3],[-1,5],[-2,5],[-5,16],[-5,12],[-1,5],[0,4],[4,5],[3,4],[2,7],[0,5],[-4,8],[-3,6],[0,7],[1,5],[2,8],[14,19],[5,13],[-1,0],[-7,-4],[-12,7],[-12,10],[-4,2],[-5,1],[-12,-1],[-4,2],[-3,2],[-2,2],[-2,5],[-2,3],[-9,9],[-1,3],[-7,8],[-64,49],[-7,-1],[-6,-2],[-19,-13],[-7,-2],[-5,-1],[-7,0],[-5,3],[-14,10],[-4,5],[-2,4],[-1,6],[-1,3],[-1,3],[-2,1],[-19,15],[-14,18],[0,1],[-19,30],[-1,5],[-1,7],[1,5],[-1,7],[-1,5],[-2,3],[-11,11],[-6,5],[-5,2],[-1,2],[0,2],[4,16],[2,8],[3,3],[2,3],[3,2],[0,1],[0,1],[-10,6],[-4,5],[-1,4],[2,3],[5,2],[17,6],[4,2],[2,4],[2,5],[-2,2],[-3,1],[-3,0],[-4,0],[-4,1],[-5,6],[-1,4],[1,4],[26,33],[4,6],[3,10],[2,3],[2,3],[2,2],[9,4],[3,2],[2,2],[4,7],[2,1],[3,2],[6,2],[22,1],[4,1],[4,4],[0,3],[-2,3],[-3,1],[-16,4],[-3,4],[-2,3],[-2,10],[0,2],[2,6],[3,6],[5,4],[13,8],[4,5],[2,3],[-1,9],[-1,0],[-73,5],[-4,3],[-17,16],[-24,15],[-16,13],[-22,13],[-2,2],[-3,3],[-1,3],[-2,4],[-1,4],[-1,8],[0,3],[0,4],[1,3],[7,11],[5,5],[3,1],[29,11],[17,10],[7,2],[50,3],[4,3],[6,12],[17,13],[5,5],[3,5],[1,3],[-1,4],[-3,3],[-16,17],[-3,0],[-3,0],[-3,-1],[-13,-11],[-18,-8],[-2,-2],[-3,-3],[-3,-6],[-2,-2],[-2,-2],[-4,-2],[-5,-1],[-7,1],[-3,1],[0,3],[4,5],[1,3],[0,4],[-1,3],[-2,3],[-5,7],[-3,7],[0,4],[0,5],[1,4],[2,3],[2,2],[18,9],[6,4],[4,5],[1,4],[1,4],[2,12],[1,5],[2,4],[2,2],[13,6],[3,3],[2,4],[2,9],[-1,11],[1,6],[1,4],[4,8],[3,8],[2,3],[2,3],[3,1],[4,1],[13,1],[4,2],[4,3],[4,7],[1,3],[-1,3],[-11,4],[-4,3],[-3,3],[-6,10],[-1,1],[-4,2],[-15,4],[-19,2],[-3,2],[-3,3],[-5,8],[-1,2],[-3,1],[-20,1],[-11,5],[-7,6],[-8,21],[0,4],[0,5],[1,4],[4,5],[3,2],[9,8],[3,4],[1,4],[-1,3],[-2,4],[-1,5],[-1,7],[1,5],[2,3],[7,2],[4,2],[4,4],[6,10],[3,5],[4,4],[8,5],[3,1],[3,1],[2,1],[33,21],[7,3],[12,1],[8,-2],[3,-1],[10,-12],[3,-2],[3,-1],[5,-1],[5,1],[26,6],[8,0],[8,-2],[3,-1],[34,-31],[4,-1],[6,-2],[5,2],[14,8],[6,3],[9,1],[4,2],[2,3],[1,4],[0,15],[0,3],[-2,3],[-4,9],[-1,7],[-27,14],[-24,3],[-5,2],[-3,2],[-5,10],[-16,16],[-3,5],[-1,5],[0,3],[0,4],[-4,16],[-5,12],[-17,32],[-3,5],[-32,29],[-3,4],[0,1],[-1,3],[1,3],[2,2],[24,13],[2,3],[1,4],[-1,8],[-3,5],[-3,4],[-22,20],[-41,29],[-6,2],[-24,4],[-12,4]],[[6859,3061],[0,16],[-7,10],[-10,15],[-16,28],[-23,26],[-9,14],[-1,14],[7,9],[12,6],[28,3],[13,5],[23,15],[15,0],[15,-16],[38,-85],[12,-13],[16,-12],[18,-7],[20,0],[1,2],[1,4],[2,4],[5,3],[6,-1],[9,-4],[5,-1],[11,1],[9,2],[18,9],[-4,12],[2,8],[5,6],[5,6],[6,-2],[5,0],[6,3],[6,6],[-9,0],[-33,-6],[-7,-4],[-5,-14],[-11,-5],[-7,1],[-21,2],[-28,9],[-25,15],[-20,19],[-16,20],[-75,139],[-3,12],[1,13],[8,14],[43,60],[34,37],[5,4],[6,9],[26,16],[8,9],[-56,1],[-23,9],[-18,21],[-5,31],[8,69],[-8,25],[10,16],[15,8],[60,19],[10,1],[9,-6],[5,-1],[2,4],[2,5],[5,5],[6,4],[5,2],[-8,10],[23,19],[3,15],[-12,-7],[-11,-4],[-20,-2],[-3,3],[-10,19],[-1,8],[4,5],[7,4],[5,5],[13,20],[9,8],[21,7],[7,9],[13,25],[-11,13],[-16,25],[-9,16],[-2,9],[14,4],[14,12],[10,16],[0,18],[-5,0],[-2,-14],[-9,-11],[-20,-13],[-23,-10],[-12,-8],[-5,-10],[-5,-14],[-12,-6],[-29,-2],[-9,6],[-9,13],[-4,15],[6,9],[-4,11],[-6,9],[-7,4],[-9,-4],[3,-12],[-2,-13],[-4,-12],[-2,-10],[-3,-8],[-19,-20],[-11,-19],[-7,-9],[-17,-8],[-2,-11],[2,-12],[0,-11],[-23,27],[-6,5],[-10,0],[-9,2],[-8,4],[-6,7],[2,14],[3,15],[0,14],[-10,7],[0,6],[22,6],[5,26],[-2,31],[2,19],[-11,-5],[-5,-10],[-6,-23],[6,-18],[-10,-4],[-15,1],[-10,-2],[-14,-4],[-14,11],[-23,35],[-19,20],[-9,12],[-3,15],[1,7],[3,7],[1,8],[-4,13],[-2,10],[-2,1],[-15,7],[-22,38],[-15,11],[-61,71],[-11,4],[-3,4],[-7,13],[-6,6],[4,7],[7,6],[3,3],[14,31],[17,72],[22,41],[9,23],[4,8],[6,4],[14,4],[7,4],[8,9],[10,15],[6,18],[-6,15],[21,54],[13,25],[15,15],[13,2],[7,-5],[7,-6],[10,-4],[7,1],[27,12],[-8,5],[-33,13],[17,15],[10,7],[41,10],[8,-2],[4,-4],[4,-3],[5,-4],[24,-6],[13,-1],[54,13],[12,7],[-45,0],[0,6],[12,2],[10,5],[10,3],[13,-4],[0,7],[-16,6],[-3,-1]],[[6881,4636],[3,17],[8,14],[1,4],[1,24],[3,5],[3,1],[4,-1],[25,-10],[4,-1],[11,2],[3,2],[3,3],[10,20],[4,3],[21,8],[4,3],[5,4],[2,4],[14,17],[18,22],[10,6],[11,2],[29,11],[17,10],[14,11],[8,11],[16,20],[11,7],[8,2],[4,4],[2,4],[2,7],[0,3],[0,3],[-1,2],[-2,3],[-1,4],[0,6],[1,4],[3,3],[9,6],[35,35],[57,42],[7,2],[16,3],[9,-1],[4,-2],[6,-4],[2,-2],[4,-1],[6,0],[13,7],[5,4],[3,5],[3,8],[2,5],[5,7],[4,3],[19,7],[7,6],[8,6],[19,3],[7,3],[14,7],[8,8],[6,7],[3,4],[1,4],[0,4],[-1,3],[-2,3],[-2,2],[-14,17],[-2,3],[0,3],[0,3],[0,1],[0,2],[0,2],[-1,3],[-7,11],[-8,11],[-11,16],[-10,23],[-2,6],[-1,4],[-1,3],[-2,2],[-7,7],[-2,2],[-2,3],[0,4],[-1,3],[-3,2],[-10,5],[-3,2],[-1,3],[-1,3],[0,4],[0,5],[3,2],[3,2],[8,2],[25,0],[10,2],[6,2],[5,5],[35,43],[4,5],[2,8],[3,3],[3,3],[6,4],[7,6],[3,2],[11,4],[3,2],[16,13],[3,5],[2,5],[1,14],[3,7],[3,3],[3,2],[30,9]],[[7546,5390],[8,-14],[85,-88],[10,-21],[6,-11],[14,-8],[4,-6],[3,-7],[3,-3],[6,1],[4,5],[3,4],[2,2],[8,-1],[8,-3],[8,-8],[6,-13],[-14,0],[0,-5],[8,-4],[23,5],[14,-1],[44,-26],[0,-6],[-4,-6],[2,-7],[4,-6],[7,-7],[-9,-5],[0,-7],[6,-2],[12,-10],[0,-6],[-5,-8],[3,-5],[6,-3],[5,-4],[3,-11],[2,-61],[-1,-9],[-3,-15],[-1,-5],[0,-8],[4,-19],[16,-24],[2,-16],[-1,-4],[-1,-5],[-2,-3],[-3,-4],[-3,-7],[2,-6],[2,-6],[2,-6],[3,-11],[8,-10],[15,-13],[-5,-12],[3,-6],[6,-5],[5,-9],[-2,-9],[-5,-8],[-3,-8],[3,-9],[11,-14],[3,-7],[2,-19],[6,-20],[3,-6],[2,-1],[8,-3],[3,-2],[1,-2],[2,-8],[11,-23],[5,-8],[4,-8],[3,-12],[4,-10],[7,-5]
And this is how my replacement new.json file starts out:
{"type":"Topology","objects":{"subunits":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":"id1","arcs":[[-1,-2,-3,-4]]},...
The numbers in the 'arcs' columns go much much higher in the new.json file (like into the thousands) while the numbers used in the uk.json file generally stay under 100. I think this might have something to do with the scale issues but I'm so new to json that I can't figure out how to solve the problem. I don't know how to pick a projection and data that will best map my data. Any advice? I would be glad to upload the json files but am not sure where I can do that.
Thanks!

d3.js, is it possible to append hyperlinks to GeoJSON file?

I have started to play with d3.js and json recently and after not finding answer in other threads I state my question directly here.
I wonder if its possible to accomplish following task with d3 library:
I have working example of loaded and projected geojson file made according to Scott Murray's book - Interactive Data Visualization (https://github.com/alignedleft/d3-book)
Here is my code (from book):
<html>
<head>
<title>Zoom/pan map example</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
</html>
<body>
<script type="text/javascript">
//Width and height
var w = 500;
var h = 300;
//Define map projection
var projection = d3.geo.albersUsa()
.translate([w/2, h/2])
.scale([500]);
//Define path generator
var path = d3.geo.path()
.projection(projection);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Load in GeoJSON data
d3.json("us-states.json", function(json) {
//Bind data and create one path per GeoJSON feature
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.style("fill", "steelblue");
});
</script>
<body>
</html>
json file from chapter 12 - https://github.com/alignedleft/d3-book/tree/master/chapter_12
Now,
I want - let's say - polygon representing state Washington (top left corner) to be clickable, "holding" hyperlink. In other words - is it possible to append hyperlink to that polygon ?
Second thing - is it possible to insert text (state numbers) into polygons so that text will remain inside polygons and not crossing its borders ?
I hope its clear and I would be thankful if someone skilled enough could provide solution for this problem.
Svg has a <a> tag you can insert dinamically:
http://www.w3schools.com/svg/svg_text.asp.
This is probably the way to go

Writing simple force layout app using D3.js

I am starting to learn D3.js and wanted to write a simple app using force layout. The goal is to create 3 nodes which are floating around and can be dragged using the mouse. This is how far I have gotten using the documentation, however all I see is a small black circle in top-left corner of my window (I assume all three are overlapping over there). I have put comments on each step - at least that's what I think they are doing.
<!doctype html>
<html>
<head>
<title>Simple Force Layout</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.29.1"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js?1.29.1"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?1.29.1"></script>
</head>
<body>
<div id="canvas"></div>
<script type="text/javascript">
var conf = {
canvasWidth: 600,
canvasHeight: 400
}
var nodes = [
{ 'name': 'Node 1' },
{ 'name': 'Node 2' },
{ 'name': 'Node 3' }
];
// Add nodes to force layout and start it
var force = d3.layout.force()
.nodes(nodes)
.size([conf.canvasWidth, conf.canvasHeight])
.start();
// Create an svg element
var svg = d3.select("#canvas")
.append("svg:svg")
.attr("width", conf.canvasWidth)
.attr("height", conf.canvasHeight);
// Create a circle for each node
var circle = svg.append("svg:g").selectAll("circle")
.data(force.nodes())
.enter().append("svg:circle")
.attr("r", 6)
.call(force.drag);
</script>
</body>
</html>
My questions:
What am I missing? What else do I need to do for the nodes to float around and be draggable?
I would like to have a mix or circular and rectangular nodes (based on some attribute of the node). How do I do this?
When I run the application, I see the following errors in Firebug:
"NetworkError: 404 Not Found - http://mbostock.github.com/d3/d3.geom.js?1.29.1"
d3.geom.js?1.29.1
"NetworkError: 404 Not Found - http://mbostock.github.com/d3/d3.layout.js?1.29.1"
Why is this? Some force layout examples I tried are also giving this error, but they seem to be working fine!
I will try to answer your question by showing you examples that work.
The force layout has this particularity that it starts by displaying
all the nodes in the upper part of the screen. Since your nodes have
no links between them (if they have I don't see it in your code)
it's normal that they're drawn on top of each other. You can try to
fix this initial render by setting the X and Y attributes of the
node to a random position on the screen. As for the floating
problem: I am not 100% sure this will work, as I haven't tested it,
but you could try applying different forces to your nodes, or at
least at the corners of your display window. This will assure that
they move and don't get outside of the screen (or use the window's
bounding box). Also you need to check some force attributes related
to speed and the stability of the layout if you want to be sure the
nodes will always move, not just float for some time and remain in a
fixed position. For the nodes to be draggable call force.drag as in
http://bl.ocks.org/1095795
This example shows how to present nodes with different shapes in the
force layout: http://bl.ocks.org/1062383.
I would suggest the single file version of D3 that usually has a
file called d3v2 or something similar...It might that you can not
access those files because of a network problem or CORS problem or
something similar, meaning the browser will not deliver you the
file. You seem to use a very old version of D3 (one year old?). A
version that looks more like what you see in the next snippet will
probably not throw you that error: If you
can't use the online version just download the file and put it in
the same directory.
Play with the D3 examples a little bit and read the documentation.

Categories