I have finally decided to saddle up and adopt d3 v5 syntax after years of using v3. After looking at some tutorials and examples, v5 syntax really struck me as sublime. The readability is far improved and it seems easier to integrate multiple data sources.
To my dismay, and despite my reverence of it, I couldn't quite build a visual from scratch with the new Promise
syntax. Here is my simple graph: (note I'm using hard coded data for the sake of this post, and I have commented out the .csv()
call that I'd actually use. It should still be functionally the same)
var margins = {top:50, right:50, bottom:50, left:50};
var width = window.innerWidth - margins.left - margins.right;
var height = window.innerHeight - margins.top - margins.bottom;
var sampleData = [
{'y':32, 'x':1},
{'y':20, 'x':2},
{'y':19, 'x':3},
{'y':12, 'x':4},
{'y':15, 'x':5},
{'y':19, 'x':6},
{'y':22, 'x':7},
{'y':26, 'x':8},
{'y':31, 'x':9},
{'y':36, 'x':10}
];
//var dataset = d3.csv("my-data.csv").then(function(data)
// {return data;
// });
var dataset = sampleData.then(function(data)
{return data;
});
var svg = d3.select('body').append('svg').attr('id','svg').attr('height','100%').attr('width','100%');
var myLine = dataset.then(function(data) {
Promise.all(data.map(function(d) {return {X:+d.x, Y:+d.y}}))//ensure numeric parsing
var xScale = d3.scaleLinear()
.domain(d3.extent(data, function(d) { return d.X; }))
.range([0,width]);
var yScale = d3.scaleLinear()
.domain(d3.extent(data, function(d) {return d.Y; }))
.range([height,0]);
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);
var line = d3.line()
.x(function(d) {return xScale(d.x); })
.y(function(d) {return yScale(d.y); });
var svg = d3.select('body').append('svg').attr('id','svg').attr('height','100%').attr('width','100%');
var graphGroup = svg.append('g')
.attr('transform',"translate("+margins.left+","+margins.top+")");
graphGroup.append('path')
.attr('d', function(d) {return line(data); });
graphGroup.append('g')
.attr('class', 'axis x')
.attr('transform', "translate(0,"+height+")")
.call(xAxis);
graphgroup.append('g')
.attr('class', 'axis y')
.call(yAxis);
});
I get this error in the console:
Uncaught TypeError: sampleData.then is not a function
Question
I take the point that Promise.all()
and .then()
are not always favorable for really simple data visuals, but I'd still like to know why I can't make the above script output a minimal line graph. From then, hopefully, I can slowly take the training wheels off and find my stride with v5.
I'm particularly confused with how to cast to numbers using the unary +
with Promise.