d3 multiple line graphs - csv

I have two problems I am struggling to understand or solve in my following d3 code (showing simplest version of the problem). Background is that I am trying to plot lines from a csv file (entire contents pasted at the end and full code that runs also below). The first 2 lines (to illustrate the format of csv) are:
date,cust,prod,units
2012-04-01,team1,A,34
Basically there are customers (team1, team2, team3) that purchase units of products (A, B,C,D). I am trying to draw line graphs filtered by product (A, B, C, D). This works individually. However since the units and date ranges vary for each product (A, B, C, D) I am first trying to fix my range to be maximum date range and max units sold. When I do this, the axis look correct but the graph does not get drawn. If I use just the filtered data the graphs works fine. What am I missing? I don't see any JS errors in the console. My next goal is to add and remove the graphs (via checkboxes) without redrawing anything, whats the easiest way to achieve that?
<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
#line1 {
fill: none;
stroke: steelblue;
stroke-width: 1px;
}
</style>
<div id="customer">
<input class="custCB" type="checkbox" id="D_CB" name="cust" value="D" enabled onclick="showGraph('D')"> D<br>
<input class="custCB" type="checkbox" id="C_cb" name="cust" value="C" enabled onclick="showGraph('C')"> C<br>
<input class="custCB" type="checkbox" id="B_cb" name="cust" value="B" enabled onclick="showGraph('B')"> B<br>
<input class="custCB" type="checkbox" id="A_cb" name="cust" value="A" enabled onclick="showGraph('A')"> A<br>
</div>
<body>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
showGraph("D");
function showGraph(prod_name) {
var mydomain = 5000;
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%Y-%m-%d");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().domain([mydomain, 0]).range([height, 0]);
//console.log(y);
// define the 1st line
var valueline = d3.line()
.x(function (d) {
return x(d.date);
})
.y(function (d) {
return y(d.units);
});
d3.select("svg").remove();
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("id", "parentgroup")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Get the data
d3.csv("test2.csv", function (error, tdata) {
if (error) throw error;
data = tdata.filter(e=> e.prod===prod_name);
//_data = data.filter(e=> e.cust==="team2");
//console.log("__data_", _data);
// format the data
console.log("data:", data);
data.forEach(function (d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
tdata.forEach(function (d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
x.domain(d3.extent(tdata, function (d) {
console.log(d.date);
return d.date;
}));
//console.log("data", data);
var m = d3.max(tdata, function (d) {
console.log(d.units);
var m = parseInt(d.units);
return m;
});
console.log("Max:", m);
y.domain([0, m]);
console.log("tdata:", tdata);
//console.log("data:", data);
svg.append("path")
.data([data])
.attr("id", "line1")
.attr("d", valueline);
//console.log("DATA", data);
svg.selectAll(".point")
.data(data)
.enter()
.append("circle")
.attr("class", "point")
.attr("cx", function (d) {
return x(d.date);
})
.attr("cy", function (d) {
return y(d.units);
})
.attr("r", 4)
.on("mouseover", function (d) {
console.log(d.units)
});
svg.append("g")
.attr("id", "xaxis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add the Y Axis
svg.append("g")
.attr("id", "yaxis")
.call(d3.axisLeft(y));
});
}
</script>
</body>
test2.csv
date,cust,prod,units
2012-04-01,team1,A,34
2012-04-02,team1,B,45
2012-04-03,team2,D,67
2012-04-04,team1,A,78
2012-04-05,team3,C,89
2012-04-06,team2,D,99
2012-04-07,team2,A,101
2012-04-08,team3,A,122
2012-04-09,team1,C,134
2012-04-10,team1,C,160
2012-04-11,team2,C,180
2012-04-12,team2,D,210
2012-04-13,team3,D,223
2012-04-14,team1,D,229
2012-04-15,team1,D,241
2012-04-16,team2,D,258
2012-04-17,team2,C,350
2012-04-18,team3,D,305
2012-04-19,team3,B,335
2012-04-20,team2,B,375
2012-04-21,team3,D,345
2012-04-22,team1,A,534
2012-04-23,team1,C,578
2012-04-24,team2,A,590
2012-04-25,team1,B,601
2012-04-26,team3,B,387
2012-04-27,team2,C,613
2012-04-28,team2,D,645
2012-04-29,team3,D,410
2012-04-30,team1,A,612
2012-05-01,team2,A,670
2012-05-02,team3,A,657
2012-05-03,team1,A,690
2012-05-04,team3,A,709
2012-05-05,team2,C,690
2012-05-06,team3,B,740
2012-05-07,team1,A,1000

This snippet is problematic:
data.forEach(function (d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
tdata.forEach(function (d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
tdata and data are arrays holding references to the same objects. So the second forEach is then acting on the same objects and the parseTime fails. Just do:
tdata.forEach(function(d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
var data = tdata.filter(e => e.prod === prod_name);
Here's your code all cleaned up.

Related

Create a Vertical Column Chart with D3 using CSV with Similar String Occurrences

I am seeking assistance with my script in creating a column chart with similar string occurrences listed in a CSV file. I am creating this chart using D3.js V3. The script and technique I’m using to capture the length of the items return results, but the number count of the length is not close to the actual count, very short from the expect item count. Can someone please review my script and see what is causing my length count to be way off from the actual number count. Any help, suggestion, or techniques will be greatly appreciated.
Below is a sample of the CSV file concept and D3 script. Thank you in advance.
d3.csv("../../data/teamData.csv", function(error, csv_data) {
if (error){
alert("Data didn't load, Refresh your browser");
}else{
for (var i = 0; i < csv_data.length; i++) {
if(csv_data[i].Team == "Team 1"){
team1 = csv_data[i].Team;
}
if(csv_data[i].Team == "Team 2"){
team2 = csv_data[i].Team;
}
}
}
var teamCount1 = team1.length;
var teamCount2 = team2.length;
console.log(teamCount1);//Not showing correct number count
console.log(teamCount2);//Not showing correct number count
var margin = {top: 2, right: 2, bottom: 60, left: 2},
w = 960 - margin.left - margin.right,
h = 500 - margin.top - margin.bottom;
var barPadding = 1;
var chartdata = [teamCount1, teamCount2];
var textData = ['Team 1', 'Team 2'];
var xScale = d3.scale.ordinal()
.domain(d3.range(chartdata2.length))
.rangeRoundBands([0, w], 0.05);
var yScale = d3.scale.linear()
.domain([0, d3.max(chartdata)])
.range([0, h]);
var svg = d3.select(".chartData")
.append("svg")
.attr("preserveAspectRatio", "xMidYMin")
.attr("viewBox", "0 0 1000 650")
.attr("width", "100%")
.attr("height", "100%")
.attr("display",'block')
.append("g").attr("class","stackChart2")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//Create bars
svg.selectAll("barRect")
.data(chartdata)
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i);
})
.attr("y", function(d) {
return h - yScale(d);
})
.attr("width", xScale.rangeBand())
.attr("height", function(d) {
return yScale(d);
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d * 10) + ")";
})
.on("click", function() {
sortBars();
});
//Create labels
svg.selectAll("text")
.data(chartdata)
.enter()
.append("text")
.text(function(d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return xScale(i) + xScale.rangeBand() / 2;
})
.attr("y", function(d) {
return h - yScale(d) - 10;
})
.attr("font-family", "sans-serif")
.attr("font-size", "14px")
.attr("fill", "black");
//Text Label
var yTextPadding = 20;
svg.selectAll(".bartext2")
.data(textData)
.enter()
.append("text")
.attr("class", "bartext2")
.attr("text-anchor", "middle")
.attr("fill", "black")
.attr("font-family", "sans-serif")
.style("font-size", "16px")
.attr("x", function(d,i) {return xScale(i)+xScale.rangeBand()/2;})
.attr("y", 460)
.text(function(d){return d;});
//Define sort order flag
var sortOrder = false;
//Define sort function
var sortBars = function() {
//Flip value of sortOrder
sortOrder = !sortOrder;
svg.selectAll("rect")
.sort(function(a, b) {
if (sortOrder) {
return d3.ascending(a, b);
} else {
return d3.descending(a, b);
}
})
.transition()
.delay(function(d, i) {
return i * 50;
})
.duration(1000)
.attr("x", function(d, i) {
return xScale(i);
});
}
});//End of D3 function
I was able to figure it out referencing this stackoverflow post: D3 Loading in CSV file then using only specific columns. I was able to filter out the needed column from my CSV file which was "Team", using d3 map as follow; var col2data = csv_data.map(function(d) { return d.Team });
Then I followed this stackoverflow post to filter my specific reoccurring item from the "Team" column: d3.js filter from csv file using multiple columns. This post made it possible to get the length of the items to build my column chart. All is working as expected. Below is the edited script. I hope this will help someone in the future encountering this issue.
d3.csv("../../data/teamData.csv", function(csv_data) {
//Filter CSV File to Specific Column
var col2data = csv_data.map(function(d) { return d.Team });
console.log(col2data);
//Filter CSV Column for Specific Column Item
var team1 = csv_data.filter(function(d){
if( d["Team"] == "Team 1"){
return d;
}
})
var team2 = csv_data.filter(function(d){
if( d["Team"] == "Team 2"){
return d;
}
})
console.log(team1);
var teamCount1 = team1.length;
var teamCount2 = team2.length;
//console.log(teamCount1);//Not showing correct number count
//console.log(teamCount2);//Not showing correct number count
var margin = {top: 2, right: 2, bottom: 60, left: 2},
w = 960 - margin.left - margin.right,
h = 500 - margin.top - margin.bottom;
var barPadding = 1;
var chartdata = [teamCount1, teamCount2];
var textData = ['Team 1', 'Team 2'];
var xScale = d3.scale.ordinal()
.domain(d3.range(chartdata.length))
.rangeRoundBands([0, w], 0.05);
var yScale = d3.scale.linear()
.domain([0, d3.max(chartdata)])
.range([0, h]);
var svg = d3.select(".plot-div")
.append("svg")
.attr("preserveAspectRatio", "xMidYMin")
.attr("viewBox", "0 0 1000 650")
.attr("width", "100%")
.attr("height", "100%")
.attr("display",'block')
.append("g").attr("class","stackChart2")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//Create bars
svg.selectAll("barRect")
.data(chartdata)
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i);
})
.attr("y", function(d) {
return h - yScale(d);
})
.attr("width", xScale.rangeBand())
.attr("height", function(d) {
return yScale(d);
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d * 10) + ")";
})
.on("click", function() {
sortBars();
});
//Create labels
svg.selectAll("text")
.data(chartdata)
.enter()
.append("text")
.text(function(d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return xScale(i) + xScale.rangeBand() / 2;
})
.attr("y", function(d) {
return h - yScale(d) - 10;
})
.attr("font-family", "sans-serif")
.attr("font-size", "14px")
.attr("fill", "black");
//Text Label
var yTextPadding = 20;
svg.selectAll(".bartext2")
.data(textData)
.enter()
.append("text")
.attr("class", "bartext2")
.attr("text-anchor", "middle")
.attr("fill", "black")
.attr("font-family", "sans-serif")
.style("font-size", "16px")
.attr("x", function(d,i) {return xScale(i)+xScale.rangeBand()/2;})
.attr("y", 460)
.text(function(d){return d;});
//Define sort order flag
var sortOrder = false;
//Define sort function
var sortBars = function() {
//Flip value of sortOrder
sortOrder = !sortOrder;
svg.selectAll("rect")
.sort(function(a, b) {
if (sortOrder) {
return d3.ascending(a, b);
} else {
return d3.descending(a, b);
}
})
.transition()
.delay(function(d, i) {
return i * 50;
})
.duration(1000)
.attr("x", function(d, i) {
return xScale(i);
});
}
});//End of D3 function

Legend doesn't appear, but no errors in the code (?)

I want to create a legend with my 3 classes (a, b, and c), but the legend doesn't appear on my localhost webmap. I couldn't find any errors. This is the assignment I am working on: https://github.com/NieneB/webmapping_for_beginners_v2/wiki/D3-step-3
I have tried to move the codes of the legend to another place, but this doesn't seem to work. I have checked the code if there were any ;)} etc. missing.
And these are some of my codes:
<h1>Bigfoot Field Researchers Organizations</h1>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
//Width and height
var w = 1000;
var h = 800;
//Create SVG
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// create a new SVG group element
var layerWorld = svg.append('g');
//Load in GeoJSON data
var data = d3.json("world_simple.json", function(error, data){
if (error) console.log(error);
return data
});
// create a new SVG group element
var layerYeti = svg.append('g');
//Load in GeoJSON data
var yetiData = d3.json("All_BFRO_Reports_points.json", function (error, data) {
if (error) console.log(error);
return data
});
Promise.all([data, yetiData]).then(function (values){
console.log(values[1])
console.log(data)
//Bind data and create one path per GeoJSON feature
layerWorld.selectAll("path")
.data(values[0].features)
.enter()
.append("path")
.attr("class", "countries")
.attr("d", path)
.style("fill", function(d){
return color(d.properties.pop_est)})
.style("stroke", "#5a5959")
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut);
layerYeti.selectAll("circle")
.data(values[1].features)
.enter()
.append("circle")
.attr("cx", function(d) {
//[0] returns the first coordinate (x) of the projected value
return projection(d.geometry.coordinates)[0];})
.attr("cy", function(d) {
//[1] returns the second coordinate (y) of the projected value
return projection(d.geometry.coordinates)[1];})
.attr("r", 2)
.style("fill", function(d){
if (d.properties.styleUrl == "#a") {return "red"}
else if (d.properties.styleUrl == "#b") {return "blue"}
else { return "yellow"}
})
.style("opacity", 0.75);
//Create Legend
var legend = d3.select("body")
.append("svg")
.attr("class", "legend")
.attr("width", 200)
.attr("height", 300);
})
var unique_values = d3.map(data.features, function(d){return d.properties.styleUrl;}).keys();
console.log(unique_values);

Bar graph is not rendering

I'm trying to duplicate this code found on bl.ocks.org, but I can't get my bar graph to render. I'm pulling from a csv instead of a tsv, but I don't think that would made a difference. There aren't any errors written to the console. Where am I going wrong?
<script type="text/javascript">
$( document ).ready(function() {
loadChart();
});
function loadChart() {
var svg = d3.select("svg");
var margin = { top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0,width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append(g).attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("Data/data.csv", function(d) {
d.NumProducts = +d.NumProducts;
return d;
}, function(error, data) {
if (error) throw error;
x.domain(data.map(function(d) { return d.Category; }));
y.domain([0, d3.max(data, function(d) { return d.NumProducts; })]);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y).ticks(10))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("Dy", "0.71em")
.attr("text-anchor", "end")
.text("Number of Products");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class" , "bar")
.attr("x", function(d) { return x(d.Category); })
.attr("y", function(d) { return y(d.NumProducts); })
.attr("width", x.bandwidth())
.attr("height", function(d) { return height - y(d.NumProducts); });
});
}
</script>
The csv:
Category,NumProducts
Beverages,12
Condiments,12
Confections,13
Dairy Products,10
Grains/Cereals,7
Meat/Poultry,6
Produce,5
Seafood,12
The main issue that you have is down to missing speech marks.
var g = svg.append(g)
Should read:
var g = svg.append("g")
If you were to inspect your DOM you would see
<svg>
<undefined transform="translate(40,20)">
... (correct DOM)
</undefined>
</svg>
The reason that nothing renders after this point, is because the browser doesn't know how to render an <undefined> element, therefore it stops trying to render.
This immediately indicated that one of the append calls wasn't working because the DOM didn't understand the type of element given to it. Making the change produces this:

Stacked Bar Chart with Time Series Data

I am new to D3.js and am using D3 v4 for this. I have already seen https://bl.ocks.org/mbostock/3886208.
Here is the .csv file (test_data.csv):
date,col_1,col_2
11/1/2012,1977652,1802851
12/1/2012,1128739,948687
1/1/2013,1201944,1514667
2/1/2013,1863148,1834006
3/1/2013,1314851,1906060
4/1/2013,1283943,1978702
5/1/2013,1127964,1195606
6/1/2013,1773254,977214
7/1/2013,1929574,1127450
8/1/2013,1980411,1808161
9/1/2013,1405691,1182788
10/1/2013,1336790,937890
11/1/2013,1851053,1358400
12/1/2013,1472623,1214610
1/1/2014,1155116,1757052
2/1/2014,1571611,1935038
3/1/2014,1898348,1320348
4/1/2014,1444838,1934789
5/1/2014,1235087,950194
6/1/2014,1272040,1580656
7/1/2014,980781,1680164
8/1/2014,1391291,1115999
9/1/2014,1211125,1542148
10/1/2014,1020824,1782795
11/1/2014,1685081,926612
12/1/2014,1469254,1767071
1/1/2015,1168523,935897
2/1/2015,1602610,1450541
3/1/2015,1830278,1354876
4/1/2015,1275158,1412555
5/1/2015,1560961,1839718
6/1/2015,949948,1587130
7/1/2015,1413765,1494446
8/1/2015,1166141,1305105
9/1/2015,958975,1202219
10/1/2015,902696,1023987
11/1/2015,961441,1865628
12/1/2015,1363145,1954046
1/1/2016,1862878,1470741
2/1/2016,1723891,1042760
3/1/2016,1906747,1169012
4/1/2016,1963364,1927063
5/1/2016,1899735,1936915
6/1/2016,1300369,1430697
7/1/2016,1777108,1401210
8/1/2016,1597045,1566763
9/1/2016,1558287,1140057
10/1/2016,1965665,1953595
11/1/2016,1800438,937551
12/1/2016,1689152,1221895
1/1/2017,1607824,1963282
2/1/2017,1878431,1415658
3/1/2017,1730296,1947106
4/1/2017,1956756,1696780
5/1/2017,1746673,1662892
6/1/2017,989702,1537646
7/1/2017,1098812,1592064
8/1/2017,1861973,1892987
9/1/2017,1129596,1406514
10/1/2017,1528632,1725020
11/1/2017,925850,1795575
Here is page.html:
<!DOCTYPE html>
<!-- https://bl.ocks.org/mbostock/3886208 -->
<style>
rect.bar { fill: steelblue; }
</style>
<script src="https://d3js.org/d3.v4.js"></script>
<body>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 900 - 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);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// parse the date / time
var parseDate = d3.timeParse("%Y-%m-%d");
var x = d3.scaleTime()
.domain([new Date(2012, 11, 1), new Date(2017, 11, 31)])
.range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var z = d3.scaleOrdinal().range(["#F1F1F1", "#CE1126"])
// load .csv file
d3.csv("test_data.csv", function(d, i, columns) {
for (i = 1, t = 0; i < columns.length; ++i) t += d[columns[i]] = +d[columns[i]];
d.total = t;
return d;
}, function(error, data){
if (error) throw error;
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var keys = data.columns.slice(1);
data.sort(function(a, b) { return b.date - a.date; });
x.domain(data.map(function(d){ return d.date }));
y.domain([0, d3.max(data, function(d) { return d.total; })]).nice();
z.domain(keys);
console.log(d3.stack().keys(keys)(data));
g.append("g")
.selectAll("g")
.data(d3.stack().keys(keys)(data))
.enter().append("g")
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("x", function(d) { return console.log(x(d.data.date)); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", x.bandwidth());
});
</script>
</body>
My aim is to create a stacked bar chart by month based on the link above (so each tick corresponds to a month), of the values in col_1 and col_2.
Some errors I've received:
console.log(x(d.data.date)), for some reason, does not return the actual date.
The following error:
Uncaught TypeError: x.bandwidth is not a function
at page.html:65
at Object. (d3.v4.js:11453)
at Dispatch.call (d3.v4.js:792)
at XMLHttpRequest.respond (d3.v4.js:11378)
I think this error might have something to do with the fact that I'm using scaleTime, rather than scaleBand, but I'm not sure.
There are some issues with your dates, which need to be in working order to use a time scale.
Firstly, Your date format is 4/1/2015 but you are parsing it with d3.timeParse("%Y-%m-%d");
You will only get null values parsing with this, to see this try:
data.forEach(function(d) {
d.date = parseDate(d.date);
console.log(d.date); // null
});
As you use slashes rather than dashes, and you use month, day, year, try:
d3.timeParse("%m/%d/%Y");
Secondly, and related to dates is that you set an initial domain based on hard coded minimum and maximum dates, that works, but you overwrite it with this:
x.domain(data.map(function(d){ return d.date }));
A timescale domain takes in a minimum and a maximum for the domain. You are providing an array of every value, instead, use:
x.domain(d3.extent( data, function(d){ return d.date }) );
On to the graph and bar width, .bandwidth() isn't a method of a continuous scale (hence your error: "Uncaught TypeError: x.bandwidth is not a function"). In a continuous scale the bars are placed based on their value, there is no natural bar width (bars are not placed with regular spacing unless the increment between each data value is the same).
As you have a data point for each month (there are no holes in the data), and each data point represents an equal length in time, we can set bar width to be a fraction of the plot area width, where the width of the plot area is split equally between each data point:
(width-margin.right-margin.left)/data.length
Here's your graph with these changes:
And here's a working example.
Lastly, note that you need to return a value here:
.attr("x", function(d) { return console.log(x(d.data.date)); })
Log before the return statement if you want to debug:
.attr("x", function(d) { console.log(x(d.date.date)); return x(d.data.date); })

How To Filter Data by Date Range on D3.js Line Chart?

I've managed to create a simple line chart using data from a csv file but I only want to display data from the last 7 days, how do I do this?
I believe I need to do a .filter somewhere but I can't find any good examples, I believe it needs to go in this block :
// Get the data
d3.csv("CSVdata.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
console.log("Date : " + d.date);
d.close = +d.close;
});
I've uploaded the chart which can be viewed here :
http://plnkr.co/edit/JyQS0X?p=preview
The html I'm using is :
<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
body { font: 12px Arial;}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
</style>
<body>
<!-- load the d3.js library -->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%d/%m/%Y").parse;
// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
// Adds the svg canvas
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 + ")");
// Get the data
d3.csv("CSVdata.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
console.log("Date : " + d.date);
d.close = +d.close;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data));
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
});
</script>
</body>
The data.csv file I'm using is
date,close
18/06/2015,49582.51
18/06/2015,50582.51
18/06/2015,52582.51
17/06/2015,52782.51
15/06/2015,55313.51
10/06/2015,58110.51
10/06/2015,55778.02
1/06/2015,53289.42
27/05/2015,53288.25
27/05/2015,50955.76
25/05/2015,48467.16
22/05/2015,49467.16
20/05/2015,49557.78
14/05/2015,50557.78
13/05/2015,53354.78
13/05/2015,50866.18
11/05/2015,48533.69
29/04/2015,49533.69
29/04/2015,47201.2
25/04/2015,44712.6
25/04/2015,45061.21
22/04/2015,45717.21
15/04/2015,45807.83
15/04/2015,43525.88
14/04/2015,41037.28
14/04/2015,42114.39
14/04/2015,42285.39
14/04/2015,43783.74
13/04/2015,46580.74
1/04/2015,48580.74
1/04/2015,46334.49
23/03/2015,43845.89
18/03/2015,43936.51
18/03/2015,41690.26
16/03/2015,39201.66
4/03/2015,41998.66
4/03/2015,39510.06
1/03/2015,37263.82
27/02/2015,37263.04
23/02/2015,37213.04
18/02/2015,34765.06
17/02/2015,32518.81
16/02/2015,30598.55
14/02/2015,33395.55
13/02/2015,36192.55
13/02/2015,36170.45
6/02/2015,36120.45
4/02/2015,36070.45
4/02/2015,33581.85
30/01/2015,31335.61
28/01/2015,31285.61
23/01/2015,21285.61
22/01/2015,21235.61
16/01/2015,21326.23
16/01/2015,21276.23
15/01/2015,21226.23
15/01/2015,18262.24
14/01/2015,10534.4
13/01/2015,10244.35
13/01/2015,12243.98
13/01/2015,92766.86
13/01/2015,82766.86
13/01/2015,42766.86
9/01/2015,22766.86
9/01/2015,22716.86
4/01/2015,22666.86
3/01/2015,22722.5
2/01/2015,22763.34
2/01/2015,22713.34
31/12/2014,22663.34
29/12/2014,22731.42
26/12/2014,22831.35
26/12/2014,22781.35
19/12/2014,22731.35
19/12/2014,22681.35
12/12/2014,22631.35
12/12/2014,22581.35
6/12/2014,22531.35
5/12/2014,22570.01
5/12/2014,22520.01
3/12/2014,22470.01
1/12/2014,51470.01
30/11/2014,51469.27
30/11/2014,51497.85
28/11/2014,51509.87
28/11/2014,51459.87
22/11/2014,51409.87
22/11/2014,51450.48
21/11/2014,51483.94
21/11/2014,1483.94
21/11/2014,1433.94
19/11/2014,1383.94
17/11/2014,1412.85
16/11/2014,1443.89
14/11/2014,1484.3
14/11/2014,1434.3
12/11/2014,1384.3
10/11/2014,1422.1
7/11/2014,1458.79
7/11/2014,1408.79
5/11/2014,1358.79
4/11/2014,1436.29
4/11/2014,1469.04
3/11/2014,1502.16
31/10/2014,1517.32
31/10/2014,1467.32
25/10/2014,1417.32
25/10/2014,1510.72
24/10/2014,1534.88
24/10/2014,1694.15
24/10/2014,1644.15
19/10/2014,1594.15
17/10/2014,1653.95
17/10/2014,1603.95
15/10/2014,1553.95
15/10/2014,1640.95
14/10/2014,1703.89
12/10/2014,1805.26
12/10/2014,1843.98
10/10/2014,1887.85
10/10/2014,1837.85
3/10/2014,1787.85
3/10/2014,1737.85
28/09/2014,1687.85
26/09/2014,1701.06
26/09/2014,1651.06
23/09/2014,1601.06
19/09/2014,1644.2
19/09/2014,1594.2
12/09/2014,1544.2
12/09/2014,1494.2
9/09/2014,1444.2
8/09/2014,1461.94
7/09/2014,1470.36
7/09/2014,1476.36
5/09/2014,1501.31
5/09/2014,1451.31
4/09/2014,1401.31
3/09/2014,1424.39
1/09/2014,1440.7
29/08/2014,1440.67
29/08/2014,1390.67
25/08/2014,1340.67
23/08/2014,1385.45
22/08/2014,1420.43
22/08/2014,1370.43
18/08/2014,1320.43
16/08/2014,1333.78
15/08/2014,1428.61
15/08/2014,1440.6
15/08/2014,1390.6
8/08/2014,1340.6
8/08/2014,1290.6
5/08/2014,1240.6
1/08/2014,1285.13
1/08/2014,1235.13
28/07/2014,1185.13
25/07/2014,1213.18
25/07/2014,1231.79
25/07/2014,1181.79
24/07/2014,1131.79
23/07/2014,1285.79
22/07/2014,1306.14
21/07/2014,1339.94
19/07/2014,1385.34
18/07/2014,1416.01
18/07/2014,1366.01
16/07/2014,1316.01
12/07/2014,1322.46
11/07/2014,1338.7
11/07/2014,1288.7
10/07/2014,1238.7
7/07/2014,1255.35
6/07/2014,1278.32
4/07/2014,1311.12
4/07/2014,1261.12
30/06/2014,1211.12
27/06/2014,1225.01
27/06/2014,1175.01
25/06/2014,1125.01
24/06/2014,1147.16
23/06/2014,1177.32
23/06/2014,1183.48
20/06/2014,1201.65
20/06/2014,1151.65
19/06/2014,1101.65
18/06/2014,1123.15
14/06/2014,1134.29
13/06/2014,1169.81
13/06/2014,1119.81
12/06/2014,1069.81
11/06/2014,1092.19
6/06/2014,1121.74
6/06/2014,1071.74
5/06/2014,1021.74
2/06/2014,1075.03
1/06/2014,1095.2
1/06/2014,1136.1
30/05/2014,1136.07
30/05/2014,1086.07
You can use the filter function (plain JavaScript)
After your data.forEach block
var cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - 90);
data = data.filter(function(d) {
return d.date > cutoffDate;
})
Adjust 90 to 7 or (max - 7) as necessary
Plunk - http://plnkr.co/edit/nnRslY8jcuMpMRDmGP4B?p=preview