Reputation: 1834
I have a working d3.js line chart that renders linear numbers: http://jsfiddle.net/2g9VQ/
var probArray = ["1.0", "0.999999931839", "0.999816434171", "0.994147880224", "0.961785353466", "0.882923015661", "0.763731336472", "0.627901360001", "0.497594590727", "0.385100568858", "0.256161790111", "0.168894610653", "0.111773057", "0.0747467808441", "0.051065424573", "0.0355360834346", "0.0251527408762", "0.018097770"];
var imlArray = ["2.0", "4.0", "6.0", "8.0", "10.0", "12.0", "14.0", "16.0", "18.0", "20.0", "23.0", "26.0", "29.0", "32.0", "35.0", "38.0", "41.0", "44.0", "47.0", "50.0", "55.0", "60.0", "65.0", "70.0", "75.0", "80.0", "85.0", "90.0", "95.0", "100.0", "110.0", "120.0", "130.0", "140.0", "150.0", "160.0", "170.0", "180.0", "190.0", "200.0", "220.0", "240.0", "260.0", "280.0", "300.0"];
function log(n) {
return Math.log(n) / Math.LN10;
}
var data = [];
for(i=0; i<probArray.length; i++) {
// without log values...
data.push([parseFloat(imlArray[i]), parseFloat(probArray[i])]);
// with log valuse...
//data.push([log(parseFloat(imlArray[i])), log(parseFloat(probArray[i]))]);
}
console.log(data);
var margin = {top: 20, right: 20, bottom: 50, left: 50},
width = 400 - margin.left - margin.right,
height = 320 - 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.x); })
.y(function(d) { return y(d.y); });
var svg = d3.select("#dialog").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 dataCallback = function(d) {
d.x = +d[0];
d.y = +d[1];
};
data.forEach(dataCallback);
x.domain(d3.extent(data, function(d) { return d.x; }));
y.domain([0, d3.max(data, function(d) { return d.y; })]);
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", line);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", 160)
.attr("y", 30)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Intensity measure type");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -50)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Probabability of exceedance in "+invest_time+" years");
var legend = d3.select("#dialog").append("svg");
legend.append("text")
.attr("x", 20)
.attr("y", 7)
.attr("dy", ".35em")
.text("Location (Lon/Lat): "+lng+", "+lat);
d3.select('#chart').on("click", function() {
data.splice(0,1);
data.push([5,5]);
dataCallback(data[data.length - 1]);
x.domain(d3.extent(data, function(d) { return d.x; }));
y.domain([0, d3.max(data, function(d) { return d.y; })]);
svg.selectAll("path").data([data])
.attr("d", line);
});
But the chart fails to render when I change the points to a logarithmic scale: http://jsfiddle.net/Z3Yms/
var probArray = ["1.0", "0.999999931839", "0.999816434171", "0.994147880224", "0.961785353466", "0.882923015661", "0.763731336472", "0.627901360001", "0.497594590727", "0.385100568858", "0.256161790111", "0.168894610653", "0.111773057", "0.0747467808441", "0.051065424573", "0.0355360834346", "0.0251527408762", "0.018097770"];
var imlArray = ["2.0", "4.0", "6.0", "8.0", "10.0", "12.0", "14.0", "16.0", "18.0", "20.0", "23.0", "26.0", "29.0", "32.0", "35.0", "38.0", "41.0", "44.0", "47.0", "50.0", "55.0", "60.0", "65.0", "70.0", "75.0", "80.0", "85.0", "90.0", "95.0", "100.0", "110.0", "120.0", "130.0", "140.0", "150.0", "160.0", "170.0", "180.0", "190.0", "200.0", "220.0", "240.0", "260.0", "280.0", "300.0"];
function log(n) {
return Math.log(n) / Math.LN10;
}
var data = [];
for(i=0; i<probArray.length; i++) {
// without log values...
//data.push([parseFloat(imlArray[i]), parseFloat(probArray[i])]);
// with log valuse...
data.push([log(parseFloat(imlArray[i])), log(parseFloat(probArray[i]))]);
}
console.log(data);
var margin = {top: 20, right: 20, bottom: 50, left: 50},
width = 400 - margin.left - margin.right,
height = 320 - 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.x); })
.y(function(d) { return y(d.y); });
var svg = d3.select("#dialog").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 dataCallback = function(d) {
d.x = +d[0];
d.y = +d[1];
};
data.forEach(dataCallback);
x.domain(d3.extent(data, function(d) { return d.x; }));
y.domain([0, d3.max(data, function(d) { return d.y; })]);
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", line);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", 160)
.attr("y", 30)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Intensity measure type");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -50)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Probabability of exceedance in "+invest_time+" years");
var legend = d3.select("#dialog").append("svg");
legend.append("text")
.attr("x", 20)
.attr("y", 7)
.attr("dy", ".35em")
.text("Location (Lon/Lat): "+lng+", "+lat);
d3.select('#chart').on("click", function() {
data.splice(0,1);
data.push([5,5]);
dataCallback(data[data.length - 1]);
x.domain(d3.extent(data, function(d) { return d.x; }));
y.domain([0, d3.max(data, function(d) { return d.y; })]);
svg.selectAll("path").data([data])
.attr("d", line);
});
I believe this is due to the numbers becoming negative along the y axis.
Upvotes: 3
Views: 6294
Reputation: 109232
You were setting the domain of the y axis as
y.domain([0, d3.max(data, function(d) { return d.y; })]);
which with the log values won't work because all values are less than 0. To fix, simply use
y.domain(d3.extent(data, function(d) { return d.y; }));
instead. You also might want to use a linear scale instead of a time scale for the x axis. Complete jsfiddle here.
Upvotes: 5