I am new to D3 and have been working along with examples and changing correcting my code using those examples,
Below is my D3 Code and it works well except the bar chart is not scaled, I seem to not understand the error on my part.
The data is coming from a TSV file and has 2 columns, 1- Categorical 2- Numerical.
<script type = "text/javascript">
var margin = { top:80, bottom:80, right:80, left:80},
width = 960 - margin.left-margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width",width + margin.left + margin.right)
.attr("height",height + margin.top + margin. bottom)
.append("g")
.attr("transform", "translate("+margin.left+"," + margin.bottom+")");
d3.tsv("ticket.tsv",function(error, data) {
dataset = data.map(function(d) { return [d["ticket"],+d["num"] ] ;})
var xScale = d3.scale.ordinal()
.domain(data.map(function(d){ return [d.ticket];}))
.rangeRoundBands([0,width],0.1);
var yScale = d3.scale.linear()
.domain([0,d3.max(data,function(d) { return Math.max([d.num]);})])
.range([height, 0]);
var rect = svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x",function(d,i) { return xScale(d.ticket);})
.attr("y",function (d) { return height - (yScale (d.num)) ;})
.attr("height",function (d) { return d.num;})
.attr("width",xScale.rangeBand())
.attr("fill","orange");
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0"+","+(height)+")")
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.call(yAxis);
;});
</script>
Here is the Solved Code and Picture, I have commented the code I have corrected.
<script type = "text/javascript">
var margin = { top:80, bottom:80, right:80, left:80},
width = 960 - margin.left-margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width",width + margin.left + margin.right)
.attr("height",height + margin.top + margin. bottom)
.append("g")
.attr("transform", "translate("+margin.left+"," + margin.bottom+")");
d3.tsv("tickets.tsv",function(error, data) {
dataset = data.map(function(d) { return [d["ticket"],+d["num"] ] ;})
var xScale = d3.scale.ordinal()
.domain(data.map(function(d){ return [d.ticket];}))
.rangeRoundBands([0,width],0.1);
var yScale = d3.scale.linear()
.domain([0,d3.max(data,function(d) { return Math.max([d.num]);})])
.range([height,0]);
var rect = svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x",function(d) { return xScale(d.ticket);})
.attr("y",function (d) { return yScale (d.num) ;})**//I made the change HERE**
.attr("height",function (d) { return height - yScale(d.num);})**// and HERE**
.attr("width",xScale.rangeBand())
.attr("fill","orange");
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0"+","+(height)+")")
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.call(yAxis);
;});
</script>
I'm adapting the zoomable and clickable map found http://bl.ocks.org/mbostock/2206340 at to plot some points and do some other things. Right now, I'm trying to make it such that on the zoom and click actions, the plotted points also move / honor the zoom. I'm not sure what in the code here is wrong, since I seem to be calling the red.circle and blue.circle objects in the zoom + click -- can anyone identify the issue? Thanks! data.csv is formatted as follows:
lon_0,lat_0,lon_1,lat_1
-122.1430195,37.4418834,-122.415278,37.778643
-122.1430195,37.4418834,-122.40815,37.785034
-122.4194155,37.7749295,-122.4330827,37.7851673
-122.4194155,37.7749295,-122.4330827,37.7851673
-118.4911912,34.0194543,-118.3672828,33.9164666
-121.8374777,39.7284944,-121.8498415,39.7241178
-115.172816,36.114646,-115.078011,36.1586877
and here is the d3.js script.
.background {
fill: none;
pointer-events: all;
}
#states path {
fill: #aaa;
stroke: #fff;
stroke-width: 1.5px;
}
#states path:hover {
stroke: white;
}
</style>
<body>
<script>
var width = 1920/2,
height = 1000/2;
var projection = d3.geo.albersUsa()
.scale(width)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var zoom = d3.behavior.zoom()
.translate(projection.translate())
.scale(projection.scale())
.scaleExtent([height, 50 * height])
.on("zoom", zoom);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("style", "stroke:black; stroke-width:2px");
var states = svg.append("g")
.attr("id", "states")
.call(zoom);
var dataset = [];
states.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height);
d3.json("us-states.json", function(json) {
states.selectAll("path")
.data(json.features)
.enter().append("path")
.attr("d", path)
.on("click", click);
d3.csv("data.csv", function(data) {
states.selectAll(".blue.circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d["lon_0"], d["lat_0"] ])[0];
})
.attr("cy", function(d) {
return projection([d["lon_0"],d["lat_0"] ])[1];
})
.attr("r", 5)
.attr("class", "blue circle")
.style("fill", "blue");
states.selectAll(".red.circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([+d["lon_1"], +d["lat_1"] ])[0];
})
.attr("cy", function(d) {
return projection([+d["lon_1"],+d["lat_1"] ])[1];
})
.attr("r", 5)
.attr("class", "red circle")
.style("fill", "red");
});
});
function click(d) {
var centroid = path.centroid(d),
translate = projection.translate();
projection.translate([
translate[0] - centroid[0] + width / 2,
translate[1] - centroid[1] + height / 2
]);
zoom.translate(projection.translate());
states.selectAll("path").transition()
.duration(1000)
.attr("d", path);
states.selectAll("red.circle").transition()
.duration(1000)
.attr("d", circle);
states.selectAll("blue.circle").transition()
.duration(1000)
.attr("d", circle);
}
function zoom() {
projection.translate(d3.event.translate).scale(d3.event.scale);
states.selectAll("path").attr("d", path);
states.selectAll("red.circle").attr("d", path);
states.selectAll("blue.circle").attr("d",path);
}
</script>
you're setting the co-ordinates of the circles when you load the map, so when you click the zoom function, your circles are displayed but are not using the same co-ordinates - i think - it will help if you can create a http://bl.ocks.org to see this.
perhaps this could be of help http://bl.ocks.org/nkhine/3150901 only UK, US and Afganistan works, but i am basically re-projecting the secondary map to fit the new zoom level.
I have setup a basic IIS server and am trying to demonstrate a d3js example. First I create an html page with the example code:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("data.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "State"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
data.sort(function(a, b) { return b.total - a.total; });
x.domain(data.map(function(d) { return d.State; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Population");
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.State) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
</script>
and then i create the data.csv file:
State,Under 5 Years,5 to 13 Years,14 to 17 Years,18 to 24 Years,25 to 44 Years,45 to 64 Years,65 Years and Over
AL,310504,552339,259034,450818,1231572,1215966,641667
AK,52083,85640,42153,74257,198724,183159,50277
AZ,515910,828669,362642,601943,1804762,1523681,862573
AR,202070,343207,157204,264160,754420,727124,407205
CA,2704659,4499890,2159981,3853788,10604510,8819342,4114496
CO,358280,587154,261701,466194,1464939,1290094,511094
CT,211637,403658,196918,325110,916955,968967,478007
DE,59319,99496,47414,84464,230183,230528,121688
DC,36352,50439,25225,75569,193557,140043,70648
FL,1140516,1938695,925060,1607297,4782119,4746856,3187797
GA,740521,1250460,557860,919876,2846985,2389018,981024
HI,87207,134025,64011,124834,356237,331817,190067
ID,121746,201192,89702,147606,406247,375173,182150
IL,894368,1558919,725973,1311479,3596343,3239173,1575308
IN,443089,780199,361393,605863,1724528,1647881,813839
IA,201321,345409,165883,306398,750505,788485,444554
KS,202529,342134,155822,293114,728166,713663,366706
KY,284601,493536,229927,381394,1179637,1134283,565867
LA,310716,542341,254916,471275,1162463,1128771,540314
ME,71459,133656,69752,112682,331809,397911,199187
MD,371787,651923,316873,543470,1556225,1513754,679565
MA,383568,701752,341713,665879,1782449,1751508,871098
MI,625526,1179503,585169,974480,2628322,2706100,1304322
MN,358471,606802,289371,507289,1416063,1391878,650519
MS,220813,371502,174405,305964,764203,730133,371598
MO,399450,690476,331543,560463,1569626,1554812,805235
MT,61114,106088,53156,95232,236297,278241,137312
NE,132092,215265,99638,186657,457177,451756,240847
NV,199175,325650,142976,212379,769913,653357,296717
NH,75297,144235,73826,119114,345109,388250,169978
NJ,557421,1011656,478505,769321,2379649,2335168,1150941
NM,148323,241326,112801,203097,517154,501604,260051
NY,1208495,2141490,1058031,1999120,5355235,5120254,2607672
NC,652823,1097890,492964,883397,2575603,2380685,1139052
ND,41896,67358,33794,82629,154913,166615,94276
OH,743750,1340492,646135,1081734,3019147,3083815,1570837
OK,266547,438926,200562,369916,957085,918688,490637
OR,243483,424167,199925,338162,1044056,1036269,503998
PA,737462,1345341,679201,1203944,3157759,3414001,1910571
RI,60934,111408,56198,114502,277779,282321,147646
SC,303024,517803,245400,438147,1193112,1186019,596295
SD,58566,94438,45305,82869,196738,210178,116100
TN,416334,725948,336312,550612,1719433,1646623,819626
TX,2027307,3277946,1420518,2454721,7017731,5656528,2472223
UT,268916,413034,167685,329585,772024,538978,246202
VT,32635,62538,33757,61679,155419,188593,86649
VA,522672,887525,413004,768475,2203286,2033550,940577
WA,433119,750274,357782,610378,1850983,1762811,783877
WV,105435,189649,91074,157989,470749,514505,285067
WI,362277,640286,311849,553914,1487457,1522038,750146
WY,38253,60890,29314,53980,137338,147279,65614
When I access the page, nothing displays...A quick look through fiddler shows the html content downloads fine (you can also see it in show source). You can also look at the data.csv file directly by accessing it from the url
http://localhost/data.csv
The problem shown in fiddler is a 406 error when d3js attempts to load the CSV file. Any ideas?
Thanks
What does your HTTP Request's Accept header contain? Apache is probably configured in such a way so as to return a 406 because the value in the Accept header does not include whatever MIME type your CSV is returning.
See
http://blogs.msdn.com/b/ieinternals/archive/2011/03/27/http-406-not-acceptable-php-ie9-standards-mode-accepts-only-text_2f00_css-for-stylesheets.aspx for a similar problem sometimes seen in browsers.
Change the build action for the csv file to "Resource" in the file's properties using your Visual Studio.