import './GraphTest.html';
import d3 from 'd3';
let SalesTotals = new Meteor.Collection(null);
function changeData() {
if(SalesTotals.find({}).count() > 0) {
let sales = SalesTotals.find({}).fetch();
for(let sale of sales) {
SalesTotals.update(sale._id, {$set: {year: sale.year, total: Math.round(Math.random() * 10000) / 100}});
}
}
else {
let startYear = Math.round(Math.random() * 10) + 2000;
let yearCount = 4;
for(let i = 0; i < yearCount; i++)
//for(let m = 0; m < 12; m++)
SalesTotals.insert({year: startYear + i/*, month: m*/, total: Math.round(Math.random() * 10000) / 100});
}
}
Template.GraphTest.onCreated(function() {
let template = Template.instance();
changeData();
});
Template.GraphTest.onRendered(function() {
////Build the SVG Graphs
let margin = {top: 20, right: 20, bottom: 30, left: 80};
let width = 960 - margin.left - margin.right;
let height = 500 - margin.top - margin.bottom;
let x0Scale = d3.scaleBand().range([0, width]).padding(0.1);
let yScale = d3.scaleLinear().range([height, 0]);
let svg = d3.select('svg.salesGraph')
.attr("viewBox", "0 0 960 500")
.attr("perserveAspectRatio", "xMidYMid meet")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
let xLabels = svg.append("g").attr("transform", "translate(0, " + height + ")");
let yLabels = svg.append("g");
Tracker.autorun(function() {
let dataset = SalesTotals.find({}).fetch();
//Update scale domains
x0Scale.domain([...new Set(dataset.map(item => item.year))]);
yScale.domain([0, d3.max(dataset, function(d) {return d.total})]);
//Join the data set with the existing data in the svg element.
let bars = svg.selectAll('.bar').data(dataset);
//Handle existing elements.
// bars.[do something here ie: attr('class', 'oldValues')]
//Handle the new data elements by adding them to the svg element.
bars.enter().append('rect')
.attr('class', 'bar')
.attr('x', function(d) {
return x0Scale(d.year);
})
.attr('width', x0Scale.bandwidth())
.attr('y', function(d) {
return yScale(d.total);
})
.attr('height', function(d) {
return height - yScale(d.total);
});
bars.transition()
// .delay(function(d, i) {
// return i / dataset.length * 1000;
// }) // this delay will make transistions sequential instead of parallel
.duration(500)
.attr("x", function(d, i) {
return x0Scale(d.year);
})
.attr("y", function(d) {
return yScale(d.total);
})
.attr("width", x0Scale.bandwidth())
.attr("height", function(d) {
return height - yScale(d.total);
});
//.attr("fill", function(d) {
// return "rgb(0, 0, " + (d.total * 10) + ")";
//});
bars.exit()
.transition()
.duration(500)
.attr("x", -x0Scale.bandwidth())
.remove();
let barTexts = svg.selectAll('text.barText').data(dataset);
barTexts.enter().append("text")
.attr("class", "barText")
.attr("text-anchor", "middle")
.attr('x', function(d) {return x0Scale(d.year) + x0Scale.bandwidth() / 2;})
.attr('y', function(d) {return yScale(d.total) - 2;})
.text(function(d) {return "$" + Math.round(d.total)});
barTexts.transition()
.duration(500)
.attr('x', function(d) {return x0Scale(d.year) + x0Scale.bandwidth() / 2;})
.attr('y', function(d) {return yScale(d.total) - 2;})
.text(function(d) {return "$" + Math.round(d.total)});
barTexts.exit()
.remove();
//Add the x & y axis labels
xLabels.attr("class", "xAxisLabels").call(d3.axisBottom(x0Scale));
yLabels.attr("class", "yAxisLabels").call(d3.axisLeft(yScale));
});
});
Template.GraphTest.helpers({
sales: function() {
let sort = [];
sort.push(['year', 'asc']);
return SalesTotals.find({}, {sort: sort});
},
formatTotal: function(total) {
return "$" + total.toFixed(2);
}
});
Template.GraphTest.events({
'click button[name="changeData"]': function(event, template) {
changeData();
}
});
/*
//Select…
let bars = svg.selectAll("rect").data(dataset, key);
//Enter…
bars.enter()
.append("rect")
.attr("x", w)
.attr("y", function(d) {
return h - yScale(d.total);
})
//.attr("width", x0Scale.rangeBand())
.attr("width", x0Scale.bandwidth())
.attr("height", function(d) {
return yScale(d.total);
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d.total * 10) + ")";
})
.attr("data-id", function(d){
return d._id;
});
//Update…
bars.transition()
// .delay(function(d, i) {
// return i / dataset.length * 1000;
// }) // this delay will make transistions sequential instead of paralle
.duration(500)
.attr("x", function(d, i) {
return x0Scale(i);
})
.attr("y", function(d) {
return h - yScale(d.total);
})
.attr("width", x0Scale.bandwidth())
.attr("height", function(d) {
return yScale(d.total);
}).attr("fill", function(d) {
return "rgb(0, 0, " + (d.total * 10) + ")";
});
//Exit…
bars.exit()
.transition()
.duration(500)
.attr("x", -x0Scale.bandwidth())
.remove();
//Update all labels
//Select…
let labels = svg.selectAll("text")
.data(dataset, key);
//Enter…
labels.enter()
.append("text")
.text(function(d) {
return d.total;
})
.attr("text-anchor", "middle")
.attr("x", w)
.attr("y", function(d) {
return h - yScale(d.total) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white");
//Update…
labels.transition()
// .delay(function(d, i) {
// return i / dataset.length * 1000;
// }) // this delay will make transistions sequential instead of paralle
.duration(500)
.attr("x", function(d, i) {
return x0Scale(i) + x0Scale.bandwidth() / 2;
}).attr("y", function(d) {
return h - yScale(d.total) + 14;
}).text(function(d) {
return d.total;
});
//Exit…
labels.exit()
.transition()
.duration(500)
.attr("x", -x0Scale.bandwidth())
.remove();
*/