Using Ajax for real time graphical display - html

I am doing a sample project using d3js sample from bl.ocks.org to plot graph. There is a csv file which is continuously updated. My task is to read it every second and update the plot. I tried to look up ajax example to add into the d3. However bl.ocks.org did not have what I needed. Can anyone please let me know a good ajax example which I can integrate with my application.
--> next task is to get csv off and have a restful service to read data. Then it is to be parsed and graph is to be updated periodically.
Thanks in advance!
<!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-%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("data.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);
});
</script>
</body>

Related

populating the JSON data from spring mvc to d3 chart using request body

I'm tyring to poplulate the data from the server as json into d3 to generate chart.
In server side I generated the JSON object using spring as below, by just populating the data in hashmap and sending the responce through spring responce body.
#RequestMapping("/greeting1")
#ResponseBody
public LinkedHashMap<String, String> greeting1(#RequestParam(value = "name", required = false) String name,
Model model) {
LinkedHashMap<String, String> values = data.populateData();
model.addAttribute("name", values);
return values;
}
In client side I'm populating the data to a div and trying to inject into d3 as below (but dosen't work).
case 1:
var test_data=d3.select("body").selectAll("test_data");
data=test_data.html;
x.domain(data.map(function(d) { return d.x; }));
y.domain(data.map(function(d) { return d.y; }));
The above code is requiring JSON as in the following format.
case 2:
var data = [{x:0,y:0.5},{x:0.1,y:0.8},{x:0.2,y:1.1},{x:1.3,y:1.5},{x:0.4,y:2.5},{x:0.5,y:3.4},{x:0.6,y:4.3}];
x.domain(data.map(function(d) { return d.x; }));
y.domain(data.map(function(d) { return d.y; }));
How shall I generate the JSON in the format specified from the server side ( as in case 2) ?
How shall i capture the div test_data in d3 ?
complete js code for d3 as below.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta charset="utf-8"></meta>
<style>
.axis text {
font: 10px sans-serif;
}
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.line {
fill: none;
stroke-width: 1.5px;
}
.dot {
fill: #fff;
stroke: #000;
}
</style>
<script src="./d3.js"></script>
<script src="./jquery.js"></script>
<script src="./data.tsv"></script>
<script>
$(document).ready(function(){
sendAjax();
});
function sendAjax() {
$.ajax({
url: "/greeting1",
type: 'GET',
/* dataType: 'json',
data: "{\"name\":\"hmkcode\",\"id\":2}",
contentType: 'application/json',
mimeType: 'application/json',*/
success: function(data) {
//alert(data);
$('#test_data').html(data);
//alert($('#test_data').html);
callChart();
},
error:function(data,status,er) {
alert("error: "+data+" status: "+status+" er:"+er);
}
});
}
</script>
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'" />
<div id="test"></div>
<div id="test_data"></div>
<script>
function callChart()
{
var margin = {top: 40, right: 40, bottom: 40, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 1])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 1])
.range([height, 0]);
var z = d3.scale.linear()
.domain([2 / 3, 1]) // D3 3.x tension is buggy!
.range(["brown", "steelblue"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("cardinal")
.x(function(d) { return x(d.x); })
.y(function(d) { return y(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 + ")");
//d3.tsv("data.tsv", type, function(error, data) {
// if (error) throw error;
//var test_data=d3.select("body").selectAll("test_data");
//data=test_data.html;
var data = [{x:0,y:0.5},{x:0.1,y:0.8},{x:0.2,y:1.1},{x:1.3,y:1.5},{x:0.4,y:2.5},{x:0.5,y:3.4},{x:0.6,y:4.3}];
x.domain(data.map(function(d) { return d.x; }));
y.domain(data.map(function(d) { return d.y; }));
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
svg.selectAll(".line")
.data(z.ticks(6))
.enter().append("path")
.attr("class", "line")
.attr("d", function(d) { return line.tension(d)(data); })
.style("stroke", z);
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 3.5);
//});
function type(d) {
d.x = +d.x;
d.y = +d.y;
return d;
}
}
</script>
</body>
</html>
My problem is solved by using gson for constructing the Json and the solution provided by #Gerardo Furtado for fetching the div through d3.
#RequestMapping("/greeting")
public String greeting(#RequestParam(value = "name", required = false, defaultValue = "World") String name,
Model model) {
LinkedList<Data.Temp> values = data.populateData();
Gson gson = new Gson();
String output=gson.toJson(values);
model.addAttribute("name",output );
return "greeting";
}
function callChart()
{
var margin = {top: 40, right: 40, bottom: 40, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 1])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 1])
.range([height, 0]);
var z = d3.scale.linear()
.domain([2 / 3, 1]) // D3 3.x tension is buggy!
.range(["brown", "steelblue"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("cardinal")
.x(function(d) { return x(d.x); })
.y(function(d) { return y(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 + ")");
//d3.tsv("data.tsv", type, function(error, data) {
// if (error) throw error;
//var test_data=d3.select("body").selectAll("test_data");
//data=test_data.html;
var test_data = d3.select("#test_data");
var data = JSON.parse(test_data.text());
x.domain(data.map(function(d) { return d.x; }));
y.domain(data.map(function(d) { return d.y; }));
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
svg.selectAll(".line")
.data(z.ticks(6))
.enter().append("path")
.attr("class", "line")
.attr("d", function(d) { return line.tension(d)(data); })
.style("stroke", z);
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 3.5);
//});
function type(d) {
d.x = +d.x;
d.y = +d.y;
return d;
}
}

The values on x-axis are descending values on grouped bar chart using d3.js

I have transformed the vertical grouped bar chart from horizontal grouped bar chart. I have taken the code from the site https://bl.ocks.org/mbostock/3887051. The problem is when I have transformed horizontal to vertical axis the values on x-axis are not ascending but they are descending i.e., the values are 10M, 8M, 6M, 4M etc....I am not sure where I have made a mistake.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 50, left: 140},
width = 800 - margin.left - margin.right,
height = 900 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0],.1);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(y)
.orient("top").ticks(5);
var yAxis = d3.svg.axis()
.scale(x0)
.orient("left");
var svg = d3.select("body").append("svg")
.attr("height", width + margin.left + margin.right)
.attr("width", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("data.csv", function(error, data) {
if (error) throw error;
var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; });
data.forEach(function(d) {
d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; });
});
x0.domain(data.map(function(d) { return d.State; }));
x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { return d.value; }); })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0,0)")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "translate(0," + height + ")")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Population");
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "state")
.attr("transform", function(d) { return "translate(0," + x0(d.State) + ")"; });
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("height", x1.rangeBand())
.attr("y", function(d) { return x1(d.name); })
//.attr("x", function(d) { return y(d.value); })
.attr("width", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(ageNames.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 10)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 14)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
</script>
You y-scale which is used on your x-axis is defined as:
var y = d3.scale.linear()
.range([height, 0] , 0.1);
This runs it in reverse and should be:
var y = d3.scale.linear()
.range([0, height] , 0.1);

D3 nested objects should be different colors

I'm creating a line graph in which the area under the line is colored based on a variable rank that is not taken into account with plotting with date and close. I'm using d3.nest() to chunk data based on the rank and then looping through dataGroup and plotting each entry with a random color.
Based on this thought process, each of the dataGroups should be a different color, but when it plots, I only get one random color for the whole plot.
Here's a Plunker
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 12px Arial;
}
text.shadow {
stroke: #fff;
stroke-width: 2.5px;
opacity: 0.9;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
.grid .tick {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
.area {
stroke-width: 0;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 30, right: 20, bottom: 35, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
var parseDate = d3.time.format("%d-%b-%y").parse;
var color = d3.scale.category20();
var x = d3.time.scale().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 area = d3.svg.area()
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.close); });
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
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 + ")");
// function for the x grid lines
function make_x_axis() {
return d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5)
}
// function for the y grid lines
function make_y_axis() {
return d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
}
// Get the data
d3.csv("data.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
var dataGroup = d3.nest()
.key(function(d) {
return d.rank;
})
.entries(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; })]);
dataGroup.forEach(function(d, i){
svg.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
});
svg.selectAll(".area")
.style("fill",function() {
return "hsl(" + Math.random() * 360 + ",100%,50%)";
})
// Draw the x Grid lines
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(make_x_axis()
.tickSize(-height, 0, 0)
.tickFormat("")
)
// Draw the y Grid lines
svg.append("g")
.attr("class", "grid")
.call(make_y_axis()
.tickSize(-width, 0, 0)
.tickFormat("")
)
// Add the valueline path.
svg.append("path")
.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);
// Add the text label for the X axis
svg.append("text")
.attr("transform",
"translate(" + (width/2) + " ," +
(height+margin.bottom) + ")")
.style("text-anchor", "middle")
.text("Date");
// Add the white background to the y axis label for legibility
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("x", margin.top - (height / 2))
.attr("dy", ".71em")
.style("text-anchor", "end")
.attr("class", "shadow")
.text("Price ($)");
// Add the text label for the Y axis
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("x", margin.top - (height / 2))
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Price ($)");
// Add the title
svg.append("text")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("text-decoration", "underline")
.text("Price vs Date Graph");
});
</script>
</body>
You bind the complete dataset (data) to each area element. As a result, all areas are on top of each other and the fill results in just showing the top most area path.
Instead in your dataGroup.forEach() you need to bind just the data corresponding to the rank:
...svg.append("path").datum(d.values)....

D3 update line graph

I created a line graph using a csv file and now I am trying to update this graph using new data from the same csv. However when I open the file in firefox I am getting an error: ReferenceError: updateData is not defined.
Here is my code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="d3/d3.min.js"></script>
</head>
<body>
<div id="option">
<input name="updateButton"
type="button"
value="Update"
onclick="updateData()" />
</div>
<script type="text/javascript">
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 150},
width = 1000 - margin.left - margin.right,
height = 400 - 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)
.tickFormat(d3.format(".0f"))
.orient("bottom");
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.Year); })
.y(function(d) { return y(d.AttendancePerG); });
// 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("piratesAttendance.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.AttendancePerG = +d.AttendancePerG;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.AttendancePerG; })]);
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data))
.attr("stroke", "black")
.attr("stroke-width",2)
.attr("fill","none");
// 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 updateData() {
// Get the data again
d3.tsv("pittsburghAttendance", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Attendance = +d.Attendance;
});
// Scale the range of the data again
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Attendance; })]);
// 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("class", "line")
.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>
</body>
</html>
Your function updateData is defined in a callback, so it will not be in the "global" scope of your page, hence you cannot invoke it from the HTML.
Try to simply move its declaration to the beginning (or end) of your <script> tag.
Oh and also your usage of d3.csv seems incorrect.

Blank page using d3 mbostock

I have very new to d3 so please bear with me. The problem I am having is that I cannot get nor figure out why none of the http://bl.ocks.org/mbostock/ demos work after copying a pasting. I keep get blank or white pages. What am I missing?
I even downloaded the gist source file from https://gist.github.com/mbostock/3884955 and still it did not work.
Any ideas will be much appreciated because I also need to implement http://bost.ocks.org/mike/uberdata/ with its data files:
(1) http://bost.ocks.org/mike/uberdata/citites.csv
(2) http://bost.ocks.org/mike/uberdata/matrix.json
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
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.temperature); });
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.tsv("data.tsv", 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 cities = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.date, temperature: +d[name]};
})
};
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),
d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })
]);
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("Temperature (ºF)");
var city = svg.selectAll(".city")
.data(cities)
.enter().append("g")
.attr("class", "city");
city.append("path")
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
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.temperature); });
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.tsv("data.tsv", 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 cities = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.date, temperature: +d[name]};
})
};
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),
d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })
]);
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("Temperature (ºF)");
var city = svg.selectAll(".city")
.data(cities)
.enter().append("g")
.attr("class", "city");
city.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
city.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.temperature) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
});
</script>
</body>
</html>
You most likely get this message in your console:
XMLHttpRequest cannot load file:///C:/Users/Charles/Desktop/New%20folder/data.tsv. Cross origin requests are only supported for HTTP.
You need to be using a webserver in order to run this script. You might also be able to get around it within your browser settings. This is because an http request is not made by loading this file.
It is explained here how to get around this. It shouldn't take too long to set up and it will make local development much easier for you. Good luck!