d3js - TypeError: string is undefined - d3.js

I don't understand this error:
TypeError: string is undefined
function d3_time_parse(date, template, string, j) {
var c, p, i = 0, n = template.length, m = string.length;
...
Here my code:
var margin = {top: 20, right: 80, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y%m%d").parse;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.index); });
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 !== "date"; }));
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var indexes = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.date, index: +d[name]};
})
};
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(indexes, function(c) { return d3.min(c.values, function(v) { return v.index; }); }),
d3.max(indexes, function(c) { return d3.max(c.values, function(v) { return v.index; }); })
]);
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("Variation (%)");
var index = svg.selectAll(".index")
.data(indexes)
.enter().append("g")
.attr("class", "index");
index.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
index.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.index) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
});
and my csv file look like this:
Date,DAX,CAC40,FTSE,NASDAQ,Other
20060407,-0.000712859,-0.009013212,0.010819606,0.009846526,0.003082604
20060413,-0.007765968,-0.024263398,0.011238971,0.004128621,0.005952774
20060421,0.02261859,0.00330204,0.028734861,0.001688981,0.003459211
20060428,0.007170521,-0.007531405,0.010534438,-0.002416181,0.004012361
...
Could someone please help me?
thx
skeut

Date,DAX,CAC40,FTSE,NASDAQ,Other
JavaScript variable names are case sensitive, so when parsing CSV file with headers as above you need to refer to fields with:
d.Date // note the uppercase D
d.DAX // note all uppercase
Here's an example from d3 wiki https://github.com/mbostock/d3/wiki/CSV#wiki-parse
Year,Make,Model,Length
1997,Ford,E350,2.34
2000,Mercury,Cougar,2.38
When parsed with d3's CSV parser, the resulting data will be represented by the following array:
[
{"Year": "1997", "Make": "Ford", "Model": "E350", "Length": "2.34"},
{"Year": "2000", "Make": "Mercury", "Model": "Cougar", "Length": "2.38"}
]
Note the uppercase object keys. To access the year of the first entry, a "Year" with an uppercase Y in data[0].Year would be necessary.
Thus in your forEach function you'll need:
data.forEach(function (d) {
d.Date = parseDate(d.Date);
});
... and later on:
return {date: d.Date, index: +d[name]};

Related

D3 Add Dots to Stacked Area Chart

I need to add dots to the stacked area chart in the code below. I've tried numerous iterations in the code with .data(layers), but it errors out when looking for cx and cy on all the iterations I've tried. The main issue is that i don't understand how to drill into the layers variable to get the cummulative summation so the circles match the lines in the stacked area.
Here's a fiddle, and heres a snippet:
var data = d3.csv.parse(d3.select("#dataset").text());
d3.select("#dataset").remove();
var format = d3.time.format("%m/%d/%y");
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var z = d3.scale.category20c();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.days);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var stack = d3.layout.stack()
.offset("zero")
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.value; });
var nest = d3.nest()
.key(function(d) { return d.key; });
var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) { return x(d.date); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
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 mygroups = d3.map(data, function(d){return(d.key)}).keys()
var color = d3.scale.ordinal()
.domain(mygroups)
.range(['#CA999A','#99A3B0','#9FBD9F'])
data.forEach(function(d) {
d.date = format.parse(d.date);
d.value = +d.value;
});
var layers = stack(nest.entries(data));
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
svg.selectAll(".layer")
.data(layers)
.enter()
.append("path")
.attr("class", "layer")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d, i) { return color(i); })
.style("stroke","black");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("path","line")
.style({
fill: "none",
stroke: "#000",
"shape-rendering":"crispEdges"
});
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.selectAll("path","line")
.style({
fill: "none",
stroke: "#000",
"shape-rendering":"crispEdges"
});
//adds dots where original data would go but without error
/* svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("class", "dot")
.attr("r", 5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.value); });
*/
//errors out with <circle> attribute cx: Expected length, "NaN".
//Tired various looping functions that would not work.
//I want the dots to follow the lines in the stack.
// it does at least put a dot on the graph
svg.selectAll("circle")
.data(layers)
.enter()
.append("circle")
.attr("class", "dot")
.attr("r", 5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.value); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<pre id = "dataset">key,value,date
Group1,37,04/23/12
Group2,12,04/23/12
Group3,46,04/23/12
Group1,32,04/24/12
Group2,19,04/24/12
Group3,42,04/24/12
Group1,45,04/25/12
Group2,16,04/25/12
Group3,44,04/25/12
Group1,24,04/26/12
Group2,52,04/26/12
Group3,64,04/26/12</pre>
⚠️This question and answer both use d3v3 - d3v4+ stacks create a data array with a different structure - as such this answer may not be useful for d3v4+
Plotting circles with the data variable won't work, even if scaling, as the values returned will be for a non-cumulative line/area graph. Alternatively, plotting values in the layers variable won't work as it contains only one value per layer. Each layer in layers contains an array with all the points that belong to that layer, we can grab all of those points and plot those as circles.
Here's the layers structure:
[
{
"key": "Group1",
"values": [
{
"key": "Group1",
"value": 37,
"date": "2012-04-23T07:00:00.000Z",
"y0": 0,
"y": 37
},
...
{
"key": "Group1",
"value": 24,
"date": "2012-04-26T07:00:00.000Z",
"y0": 0,
"y": 24
}
]
},
{
"key": "Group2",
"values": [
{
"key": "Group2",
"value": 12,
"date": "2012-04-23T07:00:00.000Z",
"y0": 37,
"y": 12
},
... // an so on.
So, we can cycle through each item of layers, which means we cycle through each layer, and collect all the points. Something like this will suffice:
// Grab all coordinates of all layers:
var points = [];
layers.forEach(function(d) {
return points.push(...d.values);
})
Now, let's look at each of the items in our points array:
{
"key": "Group1",
"value": 37,
"date": "2012-04-23T07:00:00.000Z",
"y0": 0,
"y": 37
}
Here, y represents an items height, and y0 represents it's base (the bottom of the layer at that point). Since we only want to plot each point once, and we don't want to plot the 0 values of the bottom layer's y0 property, we should only plot the topmost y value (y+y0):
//adds dots where original data would go but without error
svg.selectAll("circle")
.data(points)
.enter()
.append("circle")
.attr("class", "dot")
.attr("r", 5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.y0+d.y); });
Which looks like this altogether:
var data = d3.csv.parse(d3.select("#dataset").text());
d3.select("#dataset").remove();
var format = d3.time.format("%m/%d/%y");
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var z = d3.scale.category20c();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.days);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var stack = d3.layout.stack()
.offset("zero")
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.value; });
var nest = d3.nest()
.key(function(d) { return d.key; });
var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) { return x(d.date); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
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 mygroups = d3.map(data, function(d){return(d.key)}).keys()
var color = d3.scale.ordinal()
.domain(mygroups)
.range(['#CA999A','#99A3B0','#9FBD9F'])
data.forEach(function(d) {
d.date = format.parse(d.date);
d.value = +d.value;
});
var layers = stack(nest.entries(data));
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
svg.selectAll(".layer")
.data(layers)
.enter()
.append("path")
.attr("class", "layer")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d, i) { return color(i); })
.style("stroke","black");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("path","line")
.style({
fill: "none",
stroke: "#000",
"shape-rendering":"crispEdges"
});
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.selectAll("path","line")
.style({
fill: "none",
stroke: "#000",
"shape-rendering":"crispEdges"
});
// Grab all coordinates of all layers:
var points = [];
layers.forEach(function(d) {
return points.push(...d.values);
})
//adds dots where original data would go but without error
svg.selectAll("circle")
.data(points)
.enter()
.append("circle")
.attr("class", "dot")
.attr("r", 5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.y0+d.y); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<pre id = "dataset">key,value,date
Group1,37,04/23/12
Group2,12,04/23/12
Group3,46,04/23/12
Group1,32,04/24/12
Group2,19,04/24/12
Group3,42,04/24/12
Group1,45,04/25/12
Group2,16,04/25/12
Group3,44,04/25/12
Group1,24,04/26/12
Group2,52,04/26/12
Group3,64,04/26/12</pre>

trouble accessing max of nested object data for use in a domain in D3

I have csv data with a column of years and then columns of age groups with rates:
year,15-19,20-24,25-29,...
1999,0,1.3,8.1,...
2000,0,1.3,8.3,...
.
.
I've mapped the data as shown below. Once mapped the data is in the form of:
>Array[Object, Object, ...]
Each Object is of the form:
>id:"age group"
values:Array[]
>Object
>rate: ""
>year: ""
I'm having trouble with the max value for the y.domain. It seems to be pulling the max value from my 4th object and stopping there. Any help figuring out what's wrong with the max call would be appreciated.
var svg = d3.select("svg"),
margin = {top: 20, right: 80, bottom: 30, left: 50},
width = svg.attr("width") - margin.left - margin.right,
height = svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// define scales
var x = d3.scaleLinear().range([0, width]),
y = d3.scaleLinear().range([height, 0]),
//define color scale
z = d3.scaleOrdinal(d3.schemeCategory10);
//define line generator
var line = d3.line()
.curve(d3.curveBasis)
.x(function(d) { return x(d.year); })
.y(function(d) { return y(d.rate); });
//load data
d3.csv("breaseByageSpread.csv", function(error, data) {
if(error) throw error;
var ages = data.columns.slice(1).map(function(id) {
return {
id: id,
values: data.map(function(d) {
return {year: d.year, rate: d[id]};
})
};
});
//define x axis
x.domain(d3.extent(data, function(d) { return d.year; }));
//define y axis
y.domain([
d3.min(ages, function(c) { return d3.min(c.values, function(d) { return d.rate; }); }),
d3.max(ages, function(c) { return d3.max(c.values, function(d) { return d.rate; }); })
]);
// define color scale
z.domain(ages.map(function(c) { return c.id; }));
//append x axis
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.ticks(15)
.tickFormat(d3.format('d')));
//append y axis
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -50)
.attr('x', -125)
.attr("dy", "0.71em")
.attr("fill", "#000")
.text("Rate per 100,000 ppl");
//append rate data to svg
var rate = g.selectAll(".rate")
.data(ages)
.enter().append("g")
.attr("class", "age");
//append rate path to svg
rate.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return z(d.id); });
rate.append("text")
.datum(function(d) { return {id: d.id, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.year) + "," + y(d.value.rate) + ")"; })
.attr("x", 3)
.attr("dy", "0.35em")
.style("font", "10px sans-serif")
.text(function(d) { return d.id; });
function type(d, _, columns) {
//d.date = parseTime(d.date);
for (var i = 1, n = columns.length, c; i < n; ++i) d[c = columns[i]] = +d[c];
return d;
};
});
I found the problem. The rates data was coming in as strings. To convert it to a numeric I changed the following code when loading the data:
Old:
values: data.map(function(d) {
return {year: d.year, rate: d[id]};
New:
values: data.map(function(d) {
return {year: d.year, rate: +d[id]};

Data lines disappearing when using rangePoints on x-axis ordinal scale in line chart with D3

I've adapted this code from the multi-line line chart example here. The biggest issue I'm now having after researching what changes I needed to make is that the data lines disappear when I use .rangePoints on the x-axis ordinal scale. With just .range, the x-axis displays nothing and the data lines are bunched up along the left side of the y-axis. This has something to do with the fact I altered the original code from a time scale to ordinal, but I'm stumped as to what further changes I need to make.
Code below:
var margin = {top: 20, right: 80, bottom: 30, left: 50},
width = 500 - margin.left - margin.right,
height = 280 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangePoints([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("linear")
.x(function(d) { return x(d.episodes); })
.y(function(d) { return y(d.season); });
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 !== "episodes"; }));
var seasons = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.episodes, season: +d[name]};
})
};
});
x.domain(data.map(function(d) { return d.episodes; }));
y.domain([
d3.min(seasons, function(c) { return d3.min(c.values, function(v) { return v.season; }); }),
d3.max(seasons, function(c) { return d3.max(c.values, function(v) { return v.season; }); })
]);
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("Viewership (in mlns)");
var s = svg.selectAll(".city")
.data(seasons)
.enter().append("g")
.attr("class", "city");
s.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
s.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.season) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
});

Multiseries graph using d3.v2.js

We are plotting a multilinear graph using d3.v2.js .
We are using ordinal scale for x-axis and linear scale for y-axis as we have labels(string) to be shown in x-axis
and numbers to be shown in y-axis.
In some cases graph appears to be fine , but in some cases it plots x-axis and y-axis independently and y-axis values are not in sync with x-axis values.
Also plotting starts from 0 instead of first x-axis value.
Any pointers to this issue would be of great help.
Thanks in advance.
Please find the code below.
function plotMOAGraph(data , sigPathways){
var margin = {top: 20, right: 80, bottom: 30, left: 100},
width = 960 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scale.ordinal(
(d3.range(0,sigPathways.length))).rangeBands([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.pathway); })
.y(function(d) { return y(d.score); });
var svg = d3.select("#graphDiv").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", 450 + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "pathway"; }));
var entityNames = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {pathway: d.pathway, score: +d[name]};
})
};
});
x.domain(sigPathways);
y.domain([
d3.min(entityNames, function(c) { return d3.min(c.values, function(v) { return v.score; }); }),
d3.max(entityNames, function(c) { return d3.max(c.values, function(v) { return v.score; }); })
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("dy", "9em")
.attr("dx","40em")
.style("text-anchor", "end")
.text("Pathways");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "-4em")
.style("text-anchor", "end")
.text("Pathway Scores");
var tooltip = d3.select("#graphDiv")
.append("div")
.style("visibility", "hidden")
;
var rotateXAxis = function(d) {
var name = d.substr(0, 15);
if(name !== d) {
name = name + " ... ";
}
var el = d3.select(this);
el.text('').attr("transform", "rotate(-45)").attr("text-anchor", "end").on("mouseover", showTooltip).on("mouseout",hideTooltip);
var tspan = el.append('tspan').text(name);
tspan.attr('x', 0).attr('dy', '0');
};
svg.selectAll('g.x.axis g text').each(rotateXAxis);
function showTooltip(d) {
tooltip.text(d).style("position","absolute")
.style("top", (d3.event.pageY)-10+"px")
.style("left", (d3.event.pageX)-300+"px")
.style("visibility", "visible")
.style("font-size", "12px");
}
function hideTooltip() {
tooltip.style("visibility", "hidden");
}
var entityName = svg.selectAll(".entityName")
.data(entityNames)
.enter().append("g")
.attr("class", "entityName");
entityName.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.values); })
.style("stroke", function(d) {return color(d.name); });
entityName.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.pathway) + "," + y(d.value.score) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
}

Stuck with D3 V3 zoom behaviour documentation

I am a newbie with D3 library and I am stuck with zooming on a graph.
I display correctly my data over several graphs. But when I zoom, everything goes wrong. I don't know if I miss something with Domains or Ranges or anything... so I ask.
You can find a demo of my code here: http://pastehtml.com/view/cos13vodt.html
And here is the jsFiddle example: http://jsfiddle.net/84mSQ/
And my JS code is there:
var margin = {top: 30, right: 150, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
//To parse dates as they are into the CSV
var parseDate = d3.time.format("%Y/%m/%d-%H:%M").parse;
var format = d3.time.format("%d/%m/%y-%H:%M");
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis().scale(x)
.orient("bottom");
var yAxis = d3.svg.axis().scale(y)
.orient("left")/*.ticks(30)*/;
var zoom = d3.behavior.zoom()
.x(x)
.scaleExtent([1, 2])
.on("zoom", function(scale, translate){
console.log("fonction zoom");
console.log(scale); console.log(translate);
zoomed(scale, translate);
});
// A line generator.
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.value); });
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("svg:g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);
svg.append("rect")
.attr("class", "pane")
.attr("width", width)
.attr("height", height);
// Get the data
d3.csv("./enregistrement-subset2.csv", function(data) {
color.domain(d3.keys(data[0])
.filter(function(key) {
return key !== "date" && key !== "ECS - Button A" ;
}));
data.forEach(function(d) {
//Parse the date
d.date = parseDate(d.date);
});
var dataSet = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
//parses the number by using the '+' operator
if(name == "CO2 chambre"){
return { date: d.date, value: (+d[name])/10};
}
else{
return { date: d.date, value: +d[name]};
}
})
};
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(dataSet, function(c) { var mini = d3.min(c.values, function(v) { return v.value; }); return mini; }),
d3.max(dataSet, function(c) { var maxi = d3.max(c.values, function(v) { return v.value; }); return maxi; })
]);
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("Value of");
var valueSet = svg.selectAll(".valueSet")
.data(dataSet)
.enter().append("g")
.attr("class", "valueSet");
valueSet.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); })
.call(line);
valueSet.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.value) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
//zoomed();
});
function zoomed() {
console.log("here", d3.event);
svg.select("g.x.axis").call(xAxis);
svg.select("g.y.axis").call(yAxis);
//svg.selectAll("path.line").call(line);
svg.selectAll("path.line").attr("d", line);
//d3.select("#footer span").text("Période de temps: " + x.domain().map(format).join("-"));
}
Can anybody tell me what I did wrong with this code ?
Should I re-design it ?
Are there performances issue to preview if I use a huge amount of data and what should I do then ?
var zoom = d3.behavior.zoom()
.x(x)
**.scaleExtent([1, 2])** <---
.on("zoom", function(scale, translate){
console.log("fonction zoom");
console.log(scale); console.log(translate);
zoomed(scale, translate);
});
take out the .scaleExtent([1, 2]) and check if it is working
should be
var zoom = d3.behavior.zoom()
.x(x)
.on("zoom", function(scale, translate){
console.log("fonction zoom");
console.log(scale); console.log(translate);
zoomed(scale, translate);
});
it is because your x axis is time.

Resources