how to draw line chart by d3.js? - javascript

I am using d3.js for first time
So I referred to http://bl.ocks.org/mbostock/3883245
But,after I getting data from ajax, only y axis shown.
Here's the JS code :
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%d-%b-%y").parse;
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");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
var svg = d3.select("#wishingListMsg").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.json("MYURL", function(error, data) {
if (error) throw error;console.log(data);
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
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("Price ($)");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
});
and JSON data returned by browser :
[{"date":"2016-05-03","close":"500"},{"date":"2016-05-04","close":"399"},{"date":"2016-05-11","close":"1"},{"date":"2016-05-13","close":"20"}]
HTML :
<div id="wishingListMsg"></div>
How can I modify code?

Your dates in your data are like so :
2016-05-03 //year-month-day
In the example :
24-Apr-07 //day-month-year
So your date parse was wrong. So instead of this :
var parseDate = d3.time.format("%d-%b-%y").parse;
//which is trying to parse : day, abbreviated month name (which you dont have) and year
Use this parse instead :
var parseDate = d3.time.format("%Y-%m-%d").parse;
//which will parse : year, month and day (all in integers)
Documentation of time parsing : https://github.com/d3/d3/wiki/Time-Formatting
I also added this CSS :
.line{
fill:none;
stroke:black;
stroke-width:2px;
}
If you remove this you'll find out why :) Basically, it defaults to a fill of black and no stroke so you have to remove the fill and just have the stroke of the path.
Update fiddle : https://jsfiddle.net/thatOneGuy/au1h6mvr/
var data = [{
"date": "2016-05-03",
"close": "500"
}, {
"date": "2016-05-04",
"close": "399"
}, {
"date": "2016-05-11",
"close": "1"
}, {
"date": "2016-05-13",
"close": "20"
}]
var margin = {
top: 20,
right: 20,
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 xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.close);
});
var svg = d3.select("#wishingListMsg").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 + ")");
data.forEach(function(d) {
console.log('date',d.date)
d.date = parseDate(d.date);
d.close = +d.close;
});
x.domain(d3.extent(data, function(d) {
console.log('d',d)
return d.date;
}));
y.domain([0, d3.max(data, function(d) {
return d.close;
})]);
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("Price ($)");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
.line{
fill:none;
stroke:black;
stroke-width:2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="wishingListMsg"></div>

Related

How do you change the width of a Y-axis in a D3 chart?

I have a simple, working bar chart in D3, configured as follows:
<script>
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%Y-%m").parse;
//var format = d3.timeFormat("%Y-%m");
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format("%Y-%m"));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var svg = d3.select("#arrChart").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("/chart-arr", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});
x.domain(data.map(function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.attr("width", "150")
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".91em")
.attr("width", "150")
.style("text-anchor", "end")
.text("Value ($)");
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.style("fill", "steelblue")
.attr("x", function(d) { return x(d.date); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
});
</script>
Right now the Y-axis is not wide enough to accommodate the text labels. My question is, how can I make the Y-axis wider to accommodate longer text labels on the Y-axis?
I tried attr("width") and various other tweaks but nothing is working.
Any help is greatly appreciated!
Simply by changing your margin left:
var margin = {top: 20, right: 20, bottom: 70, left: 70},
NOTE: Please try to always state which version of d3 you are using because v3 and v5 are very different in their APIs etc.
Also, always try to include some dummy data, so that the question is a minimal verifiable example - https://stackoverflow.com/help/minimal-reproducible-example
var margin = {top: 20, right: 20, bottom: 70, left: 70},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%Y-%m").parse;
//var format = d3.timeFormat("%Y-%m");
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format("%Y-%m"));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var svg = d3.select("#arrChart").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("/chart-arr", function(error, data) {
const data = [
{date: '2020-01', value: '15000'},
{date: '2020-02', value: '17000'},
{date: '2020-03', value: '10000'},
{date: '2020-04', value: '9000'}
];
data.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});
//console.log(data)
x.domain(data.map(function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.attr("width", "150")
.append("text")
.attr("transform", "rotate(0) translate(60,-20)")
.attr("y", 6)
.attr("dy", ".91em")
.attr("width", "150")
.style("text-anchor", "end")
.text("Value ($)");
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.style("fill", "steelblue")
.attr("x", function(d) { return x(d.date); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
//});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<div id="arrChart"></div>
Output:

bar height issue in bar chart of d3 js

I am trying to draw a Bar Chart using D3.js but its not working successfully. I am trying the following:
var margin = {top:40, right: 40, bottom: 70, left: 40},
width = 500 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width],.5);
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 tip = d3.tip()
.attr('class', 'd3-tip')
.html(function(d) {
return "<strong>Value:</strong> <span style='color:red'>" + d.ActiveCount + "</span>";
})
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 + ")");
svg.call(tip);
var data = [{"CreateMonth":"5","ActiveCount":"6"},
{"CreateMonth":"6","ActiveCount":"20"},
{"CreateMonth":"7","ActiveCount":"43"},
{"CreateMonth":"8","ActiveCount":"125"},
{"CreateMonth":"9","ActiveCount":"356"},
{"CreateMonth":"10","ActiveCount":"557"}];
x.domain(data.map(function(d) { return d.CreateMonth; }));
y.domain([0, d3.max(data, function(d) { return d.ActiveCount; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");
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("Active");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.CreateMonth); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.ActiveCount); })
.attr("height", function(d) { return height - y(d.ActiveCount); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
I have done this bar graph by using this tutorial http://bl.ocks.org/d3noob/8952219, but I am facing the bar(rect) height problem with uneven ActiveCount data in array object. Is some other problem that I am unable to identify?
Also, why it taking y axis as like this as shown below
and also can't determine the height of tooltip position because I think due to some un-ordered data point or some other issue..
Any suggestion should be appreciated
The problem here is that ActiveCount in your data is a string, not a number.
You have to convert it to number. For instance, using the unary plus operator:
data.forEach(function(d) {
d.ActiveCount = +d.ActiveCount;
});
Regarding the axis, you have to remove the default fill. The easiest way is using the CSS (let's also change the ticks):
line, path {
fill: none;
shape-rendering: crispEdges;
stroke: black;
}
Here is your code with those changes (without d3.tip):
var margin = {
top: 40,
right: 40,
bottom: 70,
left: 40
},
width = 500 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
var format = d3.time.format("%b");
var parser = d3.time.format("%m").parse;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .5);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(function(d){
return format(parser(d))
});
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
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 data = [{
"CreateMonth": "5",
"ActiveCount": "6"
}, {
"CreateMonth": "6",
"ActiveCount": "20"
}, {
"CreateMonth": "7",
"ActiveCount": "43"
}, {
"CreateMonth": "8",
"ActiveCount": "125"
}, {
"CreateMonth": "9",
"ActiveCount": "356"
}, {
"CreateMonth": "10",
"ActiveCount": "557"
}];
data.forEach(function(d) {
d.ActiveCount = +d.ActiveCount;
});
x.domain(data.map(function(d) {
return d.CreateMonth;
}));
y.domain([0, d3.max(data, function(d) {
return d.ActiveCount;
})]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");
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("Active");
svg.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.style("fill", "darkorange")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.CreateMonth);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.ActiveCount);
})
.attr("height", function(d) {
return height - y(d.ActiveCount);
})
line,
path {
fill: none;
shape-rendering: crispEdges;
stroke: black;
}
<script src="https://d3js.org/d3.v3.min.js"></script>

Plotting a line graph along with Bar graph in d3js. Issue with Date

I'm learning d3js using various examples found online.
I've been trying to plot a chart with dual Y axis and an X-axis. The Y axis on the left side would plot a bar chart against the X-axis and the Y-axis on the right side would plot a line chart against X-axis. The Bar graph plots as exactly as required but the line graph does not. The X-axis is date (2015-10-15 04:10). Following this example.
The code I wrote
var margin = {top: 50, right: 50, bottom: 100, left: 50},
width = 900 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%m/%d/%Y %H:%M:%S").parse;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var yTxnVol = d3.scale.linear().range([height, 0]);
var yResTime = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(yTxnVol)
.orient("left")
var yAxis2 = d3.svg.axis()
.scale(yResTime)
.orient("right")
.ticks(10);
var svg = d3.selectAll("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("../res/data.csv", function(error, data) {
data.forEach(function(d) {
d.AVRG_RESP_TIME = +d.AVRG_RESP_TIME;
d.TXN_VOL = +d.TXN_VOL;
});
x.domain(data.map(function(d) { return d.TYM; }));
yTxnVol.domain([0, d3.max(data, function(d) { return d.TXN_VOL+50; })]);
yResTime.domain([0, d3.max(data, function(d) { return d.AVRG_RESP_TIME+50; })]);
var minDate = d3.min(data, function(d){return d.TYM});
var maxDate = d3.max(data, function(d){ return d.TYM});
var xScale = d3.time.scale().range([0,width]);//.domain([minDate, maxDate]);
xScale.domain(d3.extent(data, function(d) { return new Date(d.TYM); }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
svg.append("g")
.attr("class","y axis")
.attr("transform","translate("+width+ ", 0)")
.call(yAxis2)
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.attr("class", "yhover")
.attr("x", function(d) { return x(d.TYM); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return yTxnVol(d.TXN_VOL); })
.attr("height", function(d) { return height - yTxnVol(d.TXN_VOL); })
var line = d3.svg.line()
.x(function(d) { return xScale(new Date(d.TYM));})
.y(function(d) { return d.AVRG_RESP_TIME; });
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
});
The Output Trying to make this to a meaningful line graph. Got NaN error while formatting the dates.
Could someone help me to make this a proper line graph ?
The csv data sample
TYM, AVRG_RESP_TIME, TXN_VOL
2015-10-15 04:00:00, 12, 170
2015-10-15 04:10:00, 18, 220
2015-10-15 04:20:00, 28, 251
2015-10-15 05:00:00, 19, 100
First, fix your csv file. It is improperly formatted and should not have spaces after the comma.
Second, You are trying to mix an ordinal scale and a time scale for you xAxis. This isn't going to work. For your use case, just stick with time.
Here's a reworking of your code with explanatory comments:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<script>
var margin = {
top: 50,
right: 50,
bottom: 100,
left: 50
},
width = 900 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
// x scale should be time and only time
var x = d3.time.scale().range([0, width]);
var yTxnVol = d3.scale.linear().range([height, 0]);
var yResTime = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(yTxnVol)
.orient("left")
var yAxis2 = d3.svg.axis()
.scale(yResTime)
.orient("right")
.ticks(10);
var svg = d3.selectAll("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) {
var data = [{"TYM":"2015-10-15 04:00:00","AVRG_RESP_TIME":"12","TXN_VOL":"170"},{"TYM":"2015-10-15 04:10:00","AVRG_RESP_TIME":"18","TXN_VOL":"220"},{"TYM":"2015-10-15 04:20:00","AVRG_RESP_TIME":"28","TXN_VOL":"251"},{"TYM":"2015-10-15 05:00:00","AVRG_RESP_TIME":"19","TXN_VOL":"100"}];
// just make TYM a date and keep it as a date
data.forEach(function(d) {
d.TYM = parseDate(d.TYM);
d.AVRG_RESP_TIME = +d.AVRG_RESP_TIME;
d.TXN_VOL = +d.TXN_VOL;
});
// get our min and max date in milliseconds
// set a padding around our domain of 15%
var minDate = d3.min(data, function(d){
return d.TYM;
}).getTime();
var maxDate = d3.max(data, function(d){
return d.TYM;
}).getTime();
var padDate = (maxDate - minDate) * .15;
x.domain([new Date(minDate - padDate), new Date(maxDate + padDate)]);
yTxnVol.domain([0, d3.max(data, function(d) {
return d.TXN_VOL + 50;
})]);
yResTime.domain([0, d3.max(data, function(d) {
return d.AVRG_RESP_TIME + 50;
})]);
// set an intelligent bar width
var barWidth = (width / x.ticks().length) - 20;
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ", 0)")
.call(yAxis2)
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.attr("class", "yhover")
.attr("x", function(d) {
// center bar on time
return x(d.TYM) - (barWidth / 2);
})
.attr("width", barWidth)
.attr("y", function(d) {
return yTxnVol(d.TXN_VOL);
})
.attr("height", function(d) {
return height - yTxnVol(d.TXN_VOL);
})
.style("fill","orange");
var line = d3.svg.line()
.x(function(d) {
return x(d.TYM);
})
.y(function(d) {
return d.AVRG_RESP_TIME;
});
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line)
.style("fill","none")
.style("stroke","steelblue")
.style("stoke-width","3px");
// });
</script>
</body>
</html>
The issue with the line graph filling with black was due to improper css. The new css property.
.line {
fill: none;
stroke: darkgreen;
stroke-width: 2.5px;
}
For the dates I formatted it to (%Y-%m-%d %H:%M) format and it worked.

D3 line chart Invalid value for <path> attribute

So i have the following js to create my linechart:
var data = scope.dataset;
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - 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 xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.x(function (d) {
return x(d.label);
})
.y(function (d) {
return y(d.value);
});
data.forEach(function (d) {
d.label = d.label;
d.value = d.value;
});
var svg = d3.select("#lbLineChart").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 + ")");
x.domain(d3.extent(data, function (d) {
return d.label;
}));
y.domain(d3.extent(data, function (d) {
return d.value;
}));
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("Price ($)");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
Where the data is an array of objects: {label: 'mylabel', value: 5}
Invalid value for <path> attribute
Im not quite sure what im doing wrong? ive checked the variables again and again but was unable to find where there is an error.

D3.js line chart axis

I gonna make a line chart:
d3.json("amountOfContent.json", function(data){
var margin = {top: 20, right: 20, bottom: 30, left: 50};
var x=d3.time.scale()
.domain([new Date(data[0].date), d3.time.day.offset(new Date(data[data.length - 1].date), 1)])
.range([0,width]);
var y=d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.amount; })])
.range([height,0]);
var xAxis=d3.svg.axis()
.scale(x)
.orient("bottom")
.tickPadding(8);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var parseDate = d3.time.format("%d-%b-%y").parse;
var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.amount); });
var svg = d3.select("#amount").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 + ")");
data.forEach(function(d) {
d.date = parseDate(d.date);
});
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("Численность");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
});
Everything works fine except the date axis Result of script
As you can see it's very messy. Don't understand how to make it not to display all the data and change it's format. When I change
var parseDate = d3.time.format("%d-%b-%y").parse;
for example on
var parseDate = d3.time.format("%y").parse;
Graphic disappears. Any advices?
Try this
xAxis.selectAll("text")
.attr("transform", function(d) {
return "rotate(-65)"
})
.attr("dx", "-.8em")
.attr("dy", ".15em")
.style("text-anchor","end");

Categories

Resources