How to draw a line graph using d3.js? - javascript

I am new to d3.js and am trying to graph three lines on the same plot. I'm reading from a tsv file with four columns: time, x, y, and z. This is accelerometer data. I want to plot the x,y,z columns vs time but can't seem to get it. Any suggestions?
function graph(){
// 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;
// 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.time); })
.y(function(d) { return y(d.x); });
var valueline2 = d3.svg.line()
.x(function(d) { return x(d.time); })
.y(function(d) { return y(d.y); })
var valueline3 = d3.svg.line()
.x(function(d) { return x(d.time); })
.y(function(d) { return y(d.z); });
// 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.tsv("data/data2.tsv", function(error, data) {
data.forEach(function(d) {
d.time = +d.time;
d.x = +d.x;
d.y = +d.y;
d.z = +d.z;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.time; }));
y.domain([0, d3.max(data, function(d) { return Math.max(d.x, d.y, d.z); })]);
// Add the valueline path.
svg.append("path") // Add the valueline path.
.attr("class", "line")
.attr("d", valueline(data));
svg.append("path") // Add the valueline path.
.attr("class", "line")
.style("stroke", "red")
.attr("d", valueline2(data));
svg.append("path") // Add the valueline path.
.attr("class", "line")
.style("stroke", "green")
.attr("d", valueline3(data));
// Add the X Axis
svg.append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g") // Add the Y Axis
.attr("class", "y axis")
.call(yAxis);
});}

You can add each line one at a time to the canvas but it's not very d3 or efficient. It's much better to organise your data in the appropriate way. So the the main issue is the way that the data's been prepared. In the example that Lar's pointed to the data is nested using this block of code:
var series = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
time: d.time,
score: +d[name]
};
})
};
});
And what this does is to create an array of 3 objects. Each object has a key value pair: name and
an array. In each array is another object which contains the time and score information for plotting. It is this last array of object that is passed to the line generator.
I've created a fiddle, here, that's heavily based on the example that Lar's has pointed to and it's commented throughout. The trick at this stage is to inspect the elements and use console.log
Best of luck.

Related

d3.scaleTime dates between 1890 and 1910 appear as :00 (d3.v4)

I am creating a line plot in d3 using an example I found here -> https://www.d3-graph-gallery.com/graph/line_brushZoom.html
My data contains observations from 1890 through to 2018 in the following format:
1880-01-01,1
1890-01-01,3
1890-02-02,1
1890-02-17,1
1890-03-29,1
1890-04-04,1
1890-05-04,1
1890-06-02,1
1890-06-05,1
1890-06-11,1
1890-07-01,1
1890-10-28,1
1890-12-24,1
1890-12-25,1
1891-01-29,1
1891-03-03,1
1891-06-07,1
1892-05-09,1
1893-08-20,1
1893-10-06,1
1894-03-28,1
1895-10-17,1
1896-05-25,1
1897-02-05,1
1897-07-29,1
1897-08-26,1
1898-07-05,1
1900-01-01,1
1900-08-12,1
1901-09-21,1
1903-08-16,1
1903-09-23,1
1904-02-13,1
1904-09-02,1
1904-09-04,1
1905-05-08,1
1905-07-06,1
1905-11-19,1
1906-09-24,1
1908-02-03,1
1909-01-01,1
1910-09-26,1
I noticed that the x axis scale renders dates between 1890 and 1910 with the following ticks :00
rather than 1890, 1900, 1910
The original chart code gives the following line to set the
// Add X axis --> it is a date format
var x = d3.scaleTime()
//.domain(d3.extent(data, function(d) { return d.date; }))// original line
.domain([new Date(1880, 0, 1), new Date(2018, 0, 1)]) // debugline
.range([ 0, width ]);
xAxis = svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
d3.v5 does it. little different
const xScale = d3.scaleTime().range([0,width]);
const yScale = d3.scaleLinear().rangeRound([height, 0]);
xScale.domain(d3.extent(data, function(d){
return timeConv(d.date)}));
yScale.domain([(0), d3.max(slices, function(c) {
return d3.max(c.values, function(d) {
return d.measurement + 4; });
})
]);
I can't figure out what the problem is, I tried the same data in d3.v5 and I can't reproduce the problem. I am wondering if there is some additional parsing that is required for distinct types?
Thanks
Jonathan
PS Full code was requested (copy and pasted from the d3-gallery)
<!-- Code from d3-graph-gallery.com -->
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<script>
// set the dimensions and margins of the graph
var margin = {top: 50, right: 30, bottom: 30, left: 60},
width = 900 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
.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 + ")");
//Read the data
d3.csv("all_cases.csv",
// When reading the csv, I must format variables:
function(d){
return { date : d3.timeParse("%Y-%m-%d")(d.date), value : d.value }
},
// Now I can use this dataset:
function(data) {
// Add X axis --> it is a date format
var x = d3.scaleTime()
// .domain(d3.extent(data, function(d) { return d.date; }))
.domain([new Date(1880, 0, 1), new Date(2018, 0, 1)])
.range([ 0, width ]);
xAxis = svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add Y axis
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return +d.value; })+5])
.range([ height, 0 ]);
yAxis = svg.append("g")
.call(d3.axisLeft(y));
// Add a clipPath: everything out of this area won't be drawn.
var clip = svg.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("width", width )
.attr("height", height )
.attr("x", 0)
.attr("y", 0);
// Add brushing
var brush = d3.brushX() // Add the brush feature using the d3.brush function
.extent( [ [0,0], [width,height] ] ) // initialise the brush area: start at 0,0 and finishes at width,height: it means I select the whole graph area
.on("end", updateChart) // Each time the brush selection changes, trigger the 'updateChart' function
// Create the line variable: where both the line and the brush take place
var line = svg.append('g')
.attr("clip-path", "url(#clip)")
// Add the line
line.append("path")
.datum(data)
.attr("class", "line") // I add the class line to be able to modify this line later on.
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
.x(function(d) { return x(d.date) })
.y(function(d) { return y(d.value) })
)
// Add the brushing
line
.append("g")
.attr("class", "brush")
.call(brush);
// A function that set idleTimeOut to null
var idleTimeout
function idled() { idleTimeout = null; }
// A function that update the chart for given boundaries
function updateChart() {
// What are the selected boundaries?
extent = d3.event.selection
// If no selection, back to initial coordinate. Otherwise, update X axis domain
if(!extent){
if (!idleTimeout) return idleTimeout = setTimeout(idled, 350); // This allows to wait a little bit
x.domain([ 4,8])
}else{
x.domain([ x.invert(extent[0]), x.invert(extent[1]) ])
line.select(".brush").call(brush.move, null) // This remove the grey brush area as soon as the selection has been done
}
// Update axis and line position
xAxis.transition().duration(1000).call(d3.axisBottom(x))
line
.select('.line')
.transition()
.duration(1000)
.attr("d", d3.line()
.x(function(d) { return x(d.date) })
.y(function(d) { return y(d.value) })
)
}
// If user double click, reinitialize the chart
svg.on("dblclick",function(){
x.domain(d3.extent(data, function(d) { return d.date; }))
xAxis.transition().call(d3.axisBottom(x))
line
.select('.line')
.transition()
.attr("d", d3.line()
.x(function(d) { return x(d.date) })
.y(function(d) { return y(d.value) })
)
});
})
svg.append("text")
.attr("x", 400)
.attr("y", -5)
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("text-decoration", "solid")
.text("Outbreaks 1890 - 2018");
</script>
You're using D3 v4, and the axis works with D3 v5:
<script src="https://d3js.org/d3.v4.min.js"></script>
To make your code work with v5, you have to change the syntax of d3.csv slightly, as it uses promises in v5. You don't need to change anything else.
d3.csv("all_cases.csv",
function(d){
return { date : d3.timeParse("%Y-%m-%d")(d.date), value : d.value }
})
.then(function(data) {
// code
})

D3 Graph - Inject graph into div

I have some D3 javascript that works just fine. Here is the code if it helps. The trouble is, it loads in place of the javascript, which means I have to put the javascript in the right place in the HTML to position the graph.
what I want to be able to do is have this:
<div class="graph"></div>
and have the javascript inject the graph into that div.
Can anyone pleasse help me understand how to do this.
<!-- 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-%b-%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("test3.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(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);
});
var inter = setInterval(function() {
updateData();
}, 5000);
// ** Update data section (Called from the onclick)
function updateData() {
// Get the data again
d3.csv("test3.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
// Scale the range of the data again
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// Select the section we want to apply our changes to
var svg = d3.select("body").transition();
// Make the changes
svg.select(".line") // change the line
.duration(750)
.attr("d", valueline(data));
svg.select(".x.axis") // change the x axis
.duration(750)
.call(xAxis);
svg.select(".y.axis") // change the y axis
.duration(750)
.call(yAxis);
});
}
</script>
This line:
d3.select("body")
.append("svg")
is telling d3 to append the svg to the body of the DOM. Try:
d3.select(".graph")
.append("svg")
Which finds your div by class name and appends the svg to that.

D3 line and chart graphs on the same page breaking

I am trying to render 2 graphs on the same page: chart graph and a linear graph
in html i have two divs which bind to the 2 different graphs respectively like so:
<div id="svg-container">
<div id="svg-container-avg">
The first graph that i import in html is this linear 'average' graph that just doesn't display the path or the x axis.
It works fine if i delete the chart graph which is imported straight after. I would automatically assume that there are some sort of dependencies between the two graphs, but i cannot find anything...
my first import, linear graph: scns-avg.js file contains this
// Set the dimensions of the canvas / graph
var margin = {
top: 30,
right: 20,
bottom: 70,
left: 50
},
width = 800 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
var x = d3.scale.linear().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
var valueline = d3.svg.line()
.x(function(d) {
return x(d.scnsID);
})
.y(function(d) {
return y(d.average);
});
var svg2 = d3.select("#svg-container-avg")
.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.json("scns-avg-data-retrieval.php", function(error, data) {
data.forEach(function(d) {
d.scnsID = d.scnsID;
d.average = +d.average;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) {
return d.scnsID;
}));
y.domain([0, d3.max(data, function(d) {
return d.average;
})]);
svg2.append("path") // Add the valueline path.
.style("stroke", "rgba(13, 183, 196, 0.9)")
.attr("d", valueline(data));
svg2.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) {
return x(d.scnsID);
})
.attr("cy", function(d) {
return y(d.average);
})
svg2.append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg2.append("g") // Add the Y Axis
.attr("class", "y axis")
.call(yAxis);
});
My Data structor in JSON:
[{"date":"11-Mar-16","average":"3.18","scnsID":"2"},{"date":"12-Mar-16","average":"3.09","scnsID":"3"},{"date":"15-Mar-16","average":"3.16","scnsID":"4"},{"date":"17-Mar-16","average":"3.20","scnsID":"5"}]
When trying to run the html page with both graphs being imported the scns-avg.js throws up in the console Error: Invalid value for attribute d="M43,2.8124999999999902LNaN,15.46875000000002LNaN,5.6249999999999805L471,0"
which points to valueline(data) in this part of the code
svg2.append("path")
.style("stroke", "rgba(13, 183, 196, 0.9)")
.attr("d", valueline(data));
That is dependent on this piece of code, so the problem must be lying here, but for 6 hours now i can't find the solution to this..
var valueline = d3.svg.line()
.x(function(d) { return x(d.scnsID); })
.y(function(d) { return y(d.average); });
My chart graph that gets imported next and if disabled the linear graph renders properly is as follows below:
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()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Frequency:</strong> <span style='color:rgba(13, 183, 196, 0.9)'>" + d.average + "</span>";
});
var svg = d3.select("#svg-container").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 + ")");
svg.call(tip);
// Get the data
d3.json("scns-data-retrieval.php", function(error, data) {
if (error) throw error;
data.forEach(function(d) {
d.question = d.question;
d.average = +d.average;
});
x.domain(data.map(function(d) { return d.question; }));
y.domain([0, 5]);
legendSpace = width/5;
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", 0 - margin.left)
.attr("x", 0 - (height / 3))
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Level of need for help:");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.question); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.average); })
.attr("height", function(d) { return height - y(d.average); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
});
function type(d) {
d.average = +d.average;
return d;
};
data structure in JSON:
[{"question":1,"average":3.3333333333333},{"question":2,"average":2.5},{"question":3,"average":4},{"question":4,"average":2.75},{"question":5,"average":2.75},{"question":6,"average":2.75},{"question":7,"average":3},{"question":8,"average":3},{"question":9,"average":2.75},{"question":10,"average":3.25},{"question":11,"average":3.25},{"question":12,"average":3.5},{"question":13,"average":3},{"question":14,"average":3.25},{"question":15,"average":3.5},{"question":16,"average":3.5},{"question":17,"average":3.25},{"question":18,"average":3.75},{"question":19,"average":3.5},{"question":20,"average":3},{"question":21,"average":3},{"question":22,"average":3.5},{"question":23,"average":3.25},{"question":24,"average":3.75},{"question":25,"average":3.75},{"question":26,"average":3.75},{"question":27,"average":3.5},{"question":28,"average":2.75},{"question":29,"average":2.25},{"question":30,"average":3.5},{"question":31,"average":3},{"question":32,"average":3}]
I can't do this anymore and it's driving me crazy so i am now turning to the power of stackoverflow!
After some mad research and trial and error i have fixed this problem.
When you are trying to render more than 1 graph, if they are of different type and not lets say - multiple linear graphs, but something like a linear graph with a bar chart the variable scope is getting mixed up and it's not restricted to the javascript file once it's imported into html.
To fix this problem every graph js file has to wrapped in (function(){ All your graph code goes here })();
This restricts the variable scope to just the function.

How to make SVG/D3js clickable and get values?

Here is my entire JS code, I'm really just getting started based on some example.
I would like to be able to catch a click event, wether on the whole drawing, wether on the chart line and get y value for it.
onMouseOver and onMouseOut work as intended for now.
Thank you.
//Example may be interesting: http://bl.ocks.org/byrongibson/5232838
var parseDate = d3.time.format("%d-%b-%y").parse;
var svg, d3, x, y, valueline, xAxis, yAxis, width, height;
function CreateSvg()
{
// 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;
// Set the ranges
x = d3.time.scale().range([0, width]);
y = d3.scale.linear().range([height, 0]);
// Define the axes
xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(5);
yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
// Define the line
valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
//var rect = d3.selectAll("rect");
// Adds the svg canvas
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 + ")").on("click", click)
;
}
function GetData(data)
{
data.forEach(function(d)
{
d.date = parseDate(d.date);
d.close = +d.close;
});
data.reverse();
data.push({date:parseDate('3-May-12'), close:Math.random() * 1200});
data.push({date:parseDate('4-May-12'), close:Math.random() * 1200});
data.reverse();
return data;
}
function Draw()
{
d3.csv("data.csv", function(error, data) {
data = GetData(data);
// 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; })]);
svg.text("");
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data))
.on("mouseover", onMouseOver)
.on("mouseout", onMouseOut)
.on("click", click)
;
// 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);
});
}
function click() {
alert("onclick");
}
function onMouseOver(){
alert("mouseOver");
};
function onMouseOut(){
alert("mouseOut");
};
CreateSvg();
Draw();
Draw();

mutli line plot with d3.js and JSON data

I'd like to plot a multi line graph with d3.js.
I have following data, which I get from a database and convert to JSON.
{"items":["itemID01","itemID12","itemID14","itemID15","itemID16"],
"alpha":{
"xvalue":["itemID03","itemID12","itemID14","itemID16"],
"yvalue":[0,0,0,0]},
"beta":{
"xvalue":["itemID03","itemID12","itemID16"],
"yvalue":[0,2,0]},
"gamma":{
"xvalue":["itemID03","itemID12","itemID14","itemID16"],
"yvalue":[9,10,8,9]},
"delta":{
"xvalue":["itemID12","itemID14","itemID16"],
"yvalue":[2,0,2]},
"epsilon":{
"xvalue":["itemID12"],
"yvalue":[3]}}
I got it to work with one line. When I adjusted it to multiple lines, it doesn't show any lines at all. The code is based on this tutorial by d3noob http://www.d3noob.org/2013/01/adding-more-than-one-line-to-graph-in.html
This is my javascript code:
var margin = {top: 20, right: 80, bottom: 30, left: 50},
width = 500 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangePoints([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("#chart").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 JSON data
d3.json("getdata.php", function(error, data) {
//console.log(data);
x.domain(data.items);
y.domain([0, d3.max(d3.values(data.gamma.yvalue))]);
// hardcoded for now, use d3.max(data, function(d) { return Math.max(d.alpha.yvalue, d.beta.yvalue, ...); })
// get the array keys
var keys = [];
for (var key in data){
if (data.hasOwnProperty(key) && key !== 'items') {
keys.push(key);
}
}
//console.log(keys);
var valueline = [];
var i = 0;
keys.forEach(function(k) {
valueline[i] = d3.svg.line()
//.defined(function(d) { return (d.xvalue !== null); })
.x(function(d) { return x(d.xvalue); })
.y(function(d) { return y(d.yvalue); });
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline[i](data[k]));
//console.log(data[k]);
i++;
});
// 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")
.attr("transform", "translate(-10,0)")
.call(yAxis);
});
I set up a jsfiddle with the code http://jsfiddle.net/5PcPU/
I tried different variations of having svg.append("path") in and out of the foreach loop and just one valueline element or an array. But nothing worked so far
My guess is that the error is close to those lines
.x(function(d) { return x(d.xvalue); })
.y(function(d) { return y(d.yvalue); });
since if I try to do this, I don't get any output
.x(function(d) {
console.log('test');
console.log(d.xvalue);
return x(d.xvalue); })
I could make it work by rearranging the json data. If I use an array of x AND y values instead of one array for the x values and another one for the y values, it plots like I expect it to.
So the data looks like this:
{"items":["itemID01","itemID12","itemID14","itemID15","itemID16"],
"alpha":[{"x":"itemID03","y":0},
{"x":"itemID12","y":0},
{"x":"itemID14","y":0},
{"x":"itemID16","y":0}],
"beta":[{"x":"itemID03","y":0},
{"x":"itemID12","y":2},
{"x":"itemID16","y":0}],
"gamma":[{"x":"itemID03","y":9},
{"x":"itemID12","y":10},
{"x":"itemID14","y":8},
{"x":"itemID16","y":9}],
"delta":[{"x":"itemID12","y":2},
{"x":"itemID14","y":0},
{"x":"itemID16","y":2}],
"epsilon":[{"x":"itemID12","y":3}]}

Categories