How can I create hierarchical bar chart in d3.js - javascript

I wanted to use the Sortable Bar Chart of Mike Bostock without it's transition property and sort the bars according to their lenght but I couldn't. I want the bars just like this. without interactivity.
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
body {
font: 10px sans-serif;
}
.bar rect {
fill: steelblue;
}
.bar text {
fill: white;
}
.axis path, .axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
</style>
<script src="http://mbostock.github.com/d3/d3.js"></script>
<script>
var margin = {top: 0, right: 10, bottom: 20, left: 10},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var index = d3.range(24),
data = index.map(d3.random.normal(100, 10));
var x = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, width]);
var y = d3.scale.ordinal()
.domain(index)
.rangeRoundBands([0, height], .1);
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 + ")");
var bar = svg.selectAll(".bar")
.data(data)
.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d, i) { return "translate(0," + y(i) + ")"; });
bar.append("rect")
.attr("height", y.rangeBand())
.attr("width", x);
bar.append("text")
.attr("text-anchor", "end")
.attr("x", function(d) { return x(d) - 6; })
.attr("y", y.rangeBand() / 2)
.attr("dy", ".35em")
.text(function(d, i) { return i; });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis()
.scale(x)
.orient("bottom"));
//var sort = false;
//setInterval(function() {
// if (sort = !sort) {
// index.sort(function(a, b) { return data[a] - data[b]; });
// } else {
// index = d3.range(24);
// }
// y.domain(index);
// bar.transition()
// .duration(750)
// .delay(function(d, i) { return i * 50; })
// .attr("transform", function(d, i) { return "translate(0," + y(i) + ")"; });
//}, 5000);
var hierarchy = d3.layout.partition()
.data(function(d) { return d.data; });
</script>
I removed the the code from var sort = false; part and added
var hierarchy =.. part but It's still not working. How can I make it?
Any help will be appreciated.
Thanks.

You should add the following line to sort the values:
index.sort(function(a, b) { return data[b] - data[a]; });
Check out the jsfiddle: http://jsfiddle.net/k9rcyeyo/

Related

d3.js bar chart not updating with new information from csv

I am trying to get my d3 bar graph to update with a csv and for some reason I keep getting the error that data is undefined when I run it with the live server extension, however I am not sure why because it works totally fine with a different csv. Earlier I was having a different error with this code where it would show up but only one bar would be filled in all the way to the top no matter what was selected from the dropdown. Any help would be greatly appreciated!! Here is my code:
d3 Updating Bar Chart With Dropdown
<style>
input {
position: relative;
font-size: large;
z-index: +1;
padding: .5em;
margin-bottom: .5em;
}
body {
font: 14px sans-serif;
background-color: lightgray;
}
select {
display: block;
}
.bar {
fill: rgb(209, 20, 184);
fill-opacity: 0.7;
stroke:rgb(0, 0, 0);
stroke-width:2.5; /* this changes the stroke width*/
stroke-linecap:butt;
stroke-opacity: 1.0;
}
.axis path,
.axis line {
fill: none;
stroke: rgb(0, 0, 0);
stroke-width:3; /*again stroke width*/
shape-rendering: crispEdges;
}
</style>
<h1>Bar Graph of Crashes by Light Condition</h1>
</head>
<body>
<div id='vis-container'></div>
<script type="text/javascript">
var fileName = "CSVs\TownTotalcrashesFatalsInjuryNoinjury.csv"; //Pulling Data
var conditionFields = ["Crashes", "Fatals", "Injury", "No Injury"];
d3.csv(fileName, function(error, data) { //Error CheckingS
var townMap = {};
data.forEach(function(d) {
var town = d.Town;
townMap[town] = [];
conditionFields.forEach(function(field) {
townMap[town].push( +d[field] );
});
});
makeVis(townMap);
});
var makeVis = function(townMap) {
var margin = { top: 30, right: 50, bottom: 30, left: 50 }, //Dimensions of the Visual
width = 800 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var xScale = d3.scale.ordinal() //Getting Scale for Axis
.domain(conditionFields)
.rangeRoundBands([0, width], 0.1);
var yScale = d3.scale.linear()
.range([height, 0]);
var canvas = d3.select("#vis-container") //Creating Canvas
.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 + ")");
var xAxis = d3.svg.axis() //Creation of X-Axis
.scale(xScale)
.orient("bottom");
canvas.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var yAxis = d3.svg.axis() //Creation of Y-axis
.scale(yScale)
.orient("left");
var yAxisHandleForUpdate = canvas.append("g")
.attr("class", "y axis")
.call(yAxis);
canvas.append("text") //Addition of Axis Labels And Title
.attr("transform",
"translate(" + (width/2) + " ," +
(height + margin.top + 20) + ")")
.style("text-anchor", "middle")
.text("Light Condition");
canvas.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Crashes");
canvas.append("text")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "18px")
var updateBars = function(data) { //updating for new data
yScale.domain( d3.extent(data) );
yAxisHandleForUpdate.call(yAxis);
var bars = canvas.selectAll(".bar").data(data);
bars.enter() // Add bars for new data
.append("rect")
.attr("class", "bar")
.attr("x", function(d,i) { return xScale( conditionFields[i] ); })
.attr("width", xScale.rangeBand())
.attr("y", function(d,i) { return yScale(d); })
.attr("height", function(d,i) { return height - yScale(d); });
bars //updating new bars, removing old ones
.transition().duration(250)
.attr("y", function(d,i) { return yScale(d); })
.attr("height", function(d,i) { return height - yScale(d); });
bars.exit().remove();
};
var dropdownChange = function() { //dropdown menu handler
var newTown = d3.select(this).property('value'),
newData = townMap[newTown];
updateBars(newData);
};
var towns = Object.keys(townMap).sort(); //Creating Drop Down Menu
var dropdown = d3.select("#vis-container")
.insert("select", "svg")
.on("change", dropdownChange);
dropdown.selectAll("option")
.data(towns)
.enter().append("option")
.attr("value", function (d) { return d; })
.text(function (d) {
return d[0].toUpperCase() + d.slice(1,d.length); // capitalize 1st letter
});
var initialData = townMap[ towns[0] ];
updateBars(initialData);
};
</script>
</body>
</html>

Plot bar chart using D3 JS

I am plotting a bar chart in D3.js (Version 3). Which has two axis, one is receive_data and another one is responses. I have a JSON file where I stored the data. JSON format looks like,
[{"receive_date":"2013-11-04","responses":"2"}]
In my JSON, I have two responses values for the same date 2013-11-04 .
Like,
[{"receive_date":"2013-11-04","responses":"2"},{"receive_date":"2013-11-04","responses":"8668"}
This is the JSON Source :- https://api.myjson.com/bins/gdpu7
So, when I am plotting the graph, it is not taking the sum of the values for the same receive_date instead it is showing two times. I want it to show the sum of responses. responses should be (8668+2) for the receive_date 2013-11-04
I also found it that by using reduce we can do this. I tried to use d3.json.reduce . But it is showing error d3.json.reduce is not a function.
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// scale to ordinal because x axis is not numerical
var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);
//scale to numerical value by height
var y = d3.scale.linear().range([height, 0]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width + (2 * margin.left) + margin.right) //set width
.attr("height", height + margin.top + margin.bottom); //set height
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom"); //orient bottom because x-axis will appear below the bars
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
d3.json("https://api.myjson.com/bins/gdpu7", function(error, data) {
x.domain(data.map(function(d) {
return d.receive_date
}));
y.domain([0, d3.max(data, function(d) {
return d.responses
})]);
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(" + x(d.receive_date) + ", 0)";
});
bar.append("rect")
.attr("y", function(d) {
return y(d.responses);
})
.attr("x", function(d, i) {
return x.rangeBand() + (margin.left / 2);
})
.attr("height", function(d) {
return height - y(d.responses);
})
.attr("width", x.rangeBand()); //set width base on range on ordinal data
bar.append("text")
.attr("x", x.rangeBand() + margin.left)
.attr("y", function(d) {
return y(d.responses) - 10;
})
.attr("dy", ".75em")
.text(function(d) {
return d.responses;
});
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("responses");
});
function type(d) {
d.receive_date = +d.receive_date; // coerce to number
return d;
}
#chart rect {
fill: #4aaeea;
}
#chart text {
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #fff;
shape-rendering: crispEdges;
}
body {
background: #1a1a1a;
color: #eaeaea;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chart"></div>
JSfiddle :- https://jsfiddle.net/bL9940at/
The relevant part:
var array1 = data; //input
var array2 = [];
var last_d;
array1.reduce(function (accumulator, currentValue, i) {
var r = Number(currentValue.responses),
d = currentValue.receive_date;
if (d == last_d) r += accumulator;
array2[i] = {
receive_date: d,
responses: r
};
last_d = d;
return accumulator + Number(currentValue.responses);
}, 0);
data = array2; //output
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// scale to ordinal because x axis is not numerical
var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);
//scale to numerical value by height
var y = d3.scale.linear().range([height, 0]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width + (2 * margin.left) + margin.right) //set width
.attr("height", height + margin.top + margin.bottom); //set height
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom"); //orient bottom because x-axis will appear below the bars
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
d3.json("https://api.myjson.com/bins/gdpu7", function(error, data) {
//create new arrays
var array1 = data; //input
var array2 = [];
var last_d;
array1.reduce(function (accumulator, currentValue, i) {
var r = Number(currentValue.responses),
d = currentValue.receive_date;
if (d == last_d) r += accumulator;
array2[i] = {
receive_date: d,
responses: r
};
last_d = d;
return accumulator + Number(currentValue.responses);
}, 0);
data = array2; //output
x.domain(data.map(function(d) {
return d.receive_date;
}));
y.domain([0, d3.max(data, function(d) {
return d.responses;
})*1.1]);
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(" + x(d.receive_date) + ", 0)";
});
bar.append("rect")
.attr("y", function(d) {
return y(d.responses);
})
.attr("x", function(d, i) {
return x.rangeBand() + (margin.left / 2);
})
.attr("height", function(d) {
return height - y(d.responses);
})
.attr("width", x.rangeBand()); //set width base on range on ordinal data
bar.append("text")
.attr("x", x.rangeBand() + margin.left)
.attr("y", function(d) {
return y(d.responses) - 10;
})
.attr("dy", ".75em")
.text(function(d) {
return d.responses;
});
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("responses");
});
function type(d) {
d.receive_date = +d.receive_date; // coerce to number
return d;
}
#chart rect {
fill: #4aaeea;
}
#chart text {
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #fff;
shape-rendering: crispEdges;
}
body {
background: #1a1a1a;
color: #eaeaea;
padding: 10px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://code.jquery.com/jquery-git.js"></script>
<div id="chart"></div>
</body>
</html>

Error: <rect> attribute width: Expected length, "NaN". and <text> attribute dx: Expected length, "NaN"

I want to implement a bar chart in D3, but my values on the dx axis are of type Date, data type which the D3 library should accept, but it seems to give me an error like this: attribute width: Expected length, "NaN".
This is my code:
<html>
<head>
<meta charset="utf-8">
<title>a bar graph</title>
</head>
<style>
.axis path,
.axis line{
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
.MyRect {
fill: steelblue;
}
.MyText {
fill: white;
text-anchor: middle;
}
</style>
<body>
<script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script>
var width=400;
var height=400;
var svg=d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var padding = {left:30, right:30, top:20, bottom:20};
var dataset=[10,20,30,40,33,24,12,5];
var xScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.range([0, width-padding.left-padding.right]);
var yScale = d3.scaleLinear()
.domain([0,d3.max(dataset)])
.range([height-padding.top-padding.bottom,0]);
var xAxis = d3.axisBottom()
.scale(xScale)
var yAxis = d3.axisLeft()
.scale(yScale)
var rectPadding=4;
var rects = svg.selectAll(".Myrect")
.data(dataset)
.enter()
.append("rect")
.attr("class","Myrect")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x",function(d,i){
return xScale(i) + rectPadding/2;
})
.attr("y",function(d){
return yScale(d);
})
.attr("width",xScale.range()- rectPadding)
.attr("height",function(d){
return height - padding.top - padding.bottom - yScale(d);
});
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class","MyText")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d,i){
return xScale(i) + rectPadding/2;
})
.attr("y",function(d){
return yScale(d);
})
.attr("dx",function(){
return (xScale.range() - rectPadding)/2;
})
.attr("dy",function(d){
return 20;
})
.text(function(d){
return d;
});
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
.call(xAxis);
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.call(yAxis);
</script>
</body>
</html>
And the another error: attribute dx: Expected length, "NaN". I think it arises from band scales, but after using the introduction of the official, it still can't work.
The introduction of the official:
var x = d3.scaleBand()
.domain(["a", "b", "c"])
.range([0, width]);
So when I want to call the code, I think it should be used like this in my pasted code:
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class","MyText")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d,i){
return xScale(i) + rectPadding/2;
})
.attr("y",function(d){
return yScale(d);
})
.attr("dx",function(){
return (xScale.range() - rectPadding)/2;
})
.attr("dy",function(d){
return 20;
})
.text(function(d){
return d;
});
But it seems to give me two errors. I'm a beginner. Thank you very much!
Right now, for the width of the rectangles and the dx of the texts, you're using:
xScale.range() - rectPadding
But xScale.range() returns an array, and array - number will give you a NaN. And you're not getting anywhere with a NaN...
Instead of xScale.range(), which will return an array, you should use:
xScale.bandwidth();
Which not only returns a proper number, but it's also what you're looking for.
Here is your code with that change:
<style>
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
.MyRect {
fill: steelblue;
}
.MyText {
fill: white;
text-anchor: middle;
}
</style>
<body>
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script>
var width = 400;
var height = 400;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var padding = {
left: 30,
right: 30,
top: 20,
bottom: 20
};
var dataset = [10, 20, 30, 40, 33, 24, 12, 5];
var xScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.range([0, width - padding.left - padding.right]);
var yScale = d3.scaleLinear()
.domain([0, d3.max(dataset)])
.range([height - padding.top - padding.bottom, 0]);
var xAxis = d3.axisBottom()
.scale(xScale)
var yAxis = d3.axisLeft()
.scale(yScale)
var rectPadding = 4;
var rects = svg.selectAll(".Myrect")
.data(dataset)
.enter()
.append("rect")
.attr("class", "Myrect")
.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d, i) {
return xScale(i) + rectPadding / 2;
})
.attr("y", function(d) {
return yScale(d);
})
.attr("width", xScale.bandwidth() - rectPadding)
.attr("height", function(d) {
return height - padding.top - padding.bottom - yScale(d);
});
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class", "MyText")
.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d, i) {
return xScale(i) + rectPadding / 2;
})
.attr("y", function(d) {
return yScale(d);
})
.attr("dx", function() {
return (xScale.bandwidth() - rectPadding) / 2;
})
.attr("dy", function(d) {
return 20;
})
.text(function(d) {
return d;
});
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")")
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
.call(yAxis);
</script>
</body>
PS: You don't need rectPadding. Just set the padding in the band scale:
var xScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.range([0, width-padding.left-padding.right])
.padding(0.2);//some value here
I have got the same error when element height for chart is too small due to this code (20px per row)
document.getElementById('chart').style.height = (data.getNumberOfRows() * 20) + 'px';
It was fine for several data items but when I had only a few items I got error. So I fixed it by adding some min-height
<div id="chart" style="width: 100%; min-height: 100px"></div>

D3js: scale an axis on every bar chart

I'm building a d3js chart with horizontal bars and an axis on every bar.
Here is the jsfiddle http://jsfiddle.net/juri33/r5tkL8L1/
Now the scaling is done by this function
xScale.domain([0, d3.max(data, function(d) {
return d.initvalue * 2;
})]);
I would like to scale on every bar with different values -> every bar should get an another axis.
How can i do this? Any ideas?
Here's a quick fix which scales each axis separately:
// an array of scales
// that's 5% larger then the data is representing
var xs = data.map(function(d,i){
return d3.scale
.linear()
.range([0, width])
.domain([0, d.restlifetime + (d.restlifetime * 0.05)]);
});
// set width with appropriate scale
bar.append("rect")
.attr("width", function(d,i) {
return xs[i](d.restlifetime);
})
.attr("height", barHeight - 1);
// draw an axis for each scale
bar.append("g")
.attr("class", "x axis")
.attr("transform", function(d, i) {
return "translate(0, " + scaleOffset + ")";
})
.each(function(d,i){
d3.select(this)
.call(d3.svg.axis()
.scale(xs[i])
.orient("bottom"));
});
Full code:
var margin = {
top: 50,
right: 50,
bottom: 50,
left: 50
},
width = 500 - margin.left - margin.right,
barHeight = 20,
barOffset = 30,
scaleOffset = 19;
var data = [{
bearingname: "B1",
restlifetime: 1000
}, {
bearingname: "B2",
restlifetime: 100
}, {
bearingname: "B3",
restlifetime: 400
}, {
bearingname: "B4",
restlifetime: 300
}];
var x = d3.scale.linear()
.range([0, width]);
var chart = d3.select(".chart")
.attr("width", width + margin.left + margin.right + 300)
.attr("height", function(d, i) {
return (barHeight + barOffset) * data.length + margin.top + margin.bottom;
})
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xs = data.map(function(d,i){
return d3.scale
.linear()
.range([0, width])
.domain([0, d.restlifetime + (d.restlifetime * 0.05)]);
});
var bar = chart.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) {
return "translate(0," + i * (barHeight + barOffset) + ")";
});
bar.append("rect")
.attr("width", function(d,i) {
return xs[i](d.restlifetime);
})
.attr("height", barHeight - 1);
bar.append("g")
.attr("class", "x axis")
.attr("transform", function(d, i) {
return "translate(0, " + scaleOffset + ")";
})
.each(function(d,i){
d3.select(this)
.call(d3.svg.axis()
.scale(xs[i])
.orient("bottom"));
});
bar.append("text")
.attr("x", function(d,i) {
return xs[i](d.restlifetime) - 3;
})
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.text(function(d) {
return d.restlifetime + " h";
});
bar.append("text")
.attr("x", 520)
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.style("fill", "black")
.text(function(d) {
return d.bearingname;
});
bar.append("text")
.attr("x", 600)
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.style("fill", "black")
.html("S 0, min");
.chart rect {
fill: green;
}
.chart text {
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
.bar text {
fill: black;
}
.axis text {
font: 10px sans-serif;
fill: black;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg class="chart"></svg>

The use of a data array in the d3.js scatter file instead of an external data file

I have the javascript of the scatter d3.js library:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.point {
fill: steelblue;
stroke: #000;
}
</style>
<body>
<script src="http://d3js.org/d3.v2.js?2.9.6"></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.linear()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
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(data) {
// Coerce the strings to numbers.
data.forEach(function(d) {
d.x = +d.x;
d.y = +d.y;
});
// Compute the scales’ domains.
x.domain(d3.extent(data, function(d) { return d.x; })).nice();
y.domain(d3.extent(data, function(d) { return d.y; })).nice();
// Add the x-axis.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis().scale(x).orient("bottom"));
// Add the y-axis.
svg.append("g")
.attr("class", "y axis")
.call(d3.svg.axis().scale(y).orient("left"));
// Add the points!
svg.selectAll(".point")
.data(data)
.enter().append("path")
.attr("class", "point")
.attr("d", d3.svg.symbol().type("triangle-up"))
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; });
});
</script>
The file:data.cvs
x,y
5,90
25,30
45,50
65,55
85,25
Instead of reading the data from a cvs file I added an array to the javascript and tried to extract x and y values directly from this array:
var rows = new array(
array(0,0),
array(90,90),
array(59,70),
array(65,77),
array(85,66)
);
How can I use the array rows in order to obtain the same result ??
You can use array of hash:
var data = [{"x":"5","y":"90"},{"x":"25","y":"30"},{"x":"45","y":"50"},
{"x":"65","y":"55"},{"x":"85","y":"25"}];
Or write a function to convert your array of arrays to this array of hash.
var rows = new Array(
Array(0,0),
Array(90,90),
Array(59,70),
Array(65,77),
Array(85,66)
);
for (var i = 0; i < rows.length; i++) {
data.push({x: rows[i][0], y: rows[i][1]});
}
// Coerce the strings to numbers.
data.forEach(function(d) {
d.x = +d.x;
d.y = +d.y;
});
Here's the live code:
http://vida.io/documents/THpmgQDARSWPJqGG5

Categories

Resources