Files
old-spike/client/d3/grid/calendar_grid.js
2016-02-12 16:00:05 -06:00

123 lines
4.2 KiB
JavaScript

import extend from 'extend';
import Chart from './../base';
// inspired by https://gist.github.com/mbostock/4b66c0d9be9a0d56484e
class CalendarGridChart extends Chart{
get chart_options(){
return {
grid_padding: 1,
parse_date_format: '%Y-%m-%d',
display_date_format: '%B %Y',
date_attr: 'date',
range_attr: 'z',
extent: []
};
}
defineAxes(){
var grid_chart = this;
grid_chart.y_scale = d3.scale.ordinal()
.rangeRoundBands([grid_chart.height, 0], 0.05);
grid_chart.y_axis = d3.svg.axis()
.scale(grid_chart.y_scale)
.orient("left");
grid_chart.x_scale = d3.scale.ordinal()
.rangeRoundBands([0, grid_chart.width], 0.05);
grid_chart.x_axis = d3.svg.axis()
.scale(grid_chart.x_scale)
.orient("top");
// append axes
grid_chart.svg.append("g")
.attr("class", "d3-chart-domain d3-chart-axis");
grid_chart.svg.append("g")
.attr("class", "d3-chart-range d3-chart-axis")
.attr("transform", "translate(0, " + (grid_chart.height - grid_chart.margin.top) + ")");
}
afterAxes(){
var grid_chart = this;
grid_chart.day_length = grid_chart.width / 31 - grid_chart.grid_padding * 30;
if (grid_chart.parse_date_format) grid_chart.parseDate = d3.time.format(grid_chart.parse_date_format);
if (grid_chart.display_date_format) grid_chart.displayDate = d3.time.format(grid_chart.display_date_format);
grid_chart.monthFormat = d3.time.format('%B %Y');
}
serializeData(data){
var grid_chart = this,
serialized_data = {
series: data
};
serialized_data.css_class = data.css_class || bar_chart.toClass ? bar_chart.toClass(data_set) : "";
serialized_data.title = bar_chart.titleize ? bar_chart.titleize(data_set) : "";
toDate = grid_chart.parseDate ? (d)=>{ return grid_chart.parseDate(d[grid_chart.date_attr]); } : (d)=>{ return d[grid_chart.date_attr] };
var min_range = grid_chart.extent[0] || 0,
max_range = grid_chart.extent[1] || 0;
serialized_data.months = [];
series.values.forEach((value)=>{
var date = toDate(value),
date_s = grid_chart.monthFormat(value);
min_range = Math.min(0, min_range, value[grid_chart.range_attr]);
max_range = Math.max(max_range, value[grid_chart.range_attr]);
if (serialized_data.months.indexOf(date_s) < 0) serialized_data.months.push(date_s);
});
serialized_data.range ={
min: min_range,
max: max_range,
diff: max_range - min_range };
serialized_data.months = serialized_data.months.sort((date_s1, date_s2)=>{
var date1 = grid_chart.monthFormat(date_s1),
date2 = grid_chart.monthFormat(date_s2);
return date1.toTime() - date2.toTime();
});
return serialized_data;
};
drawData(data){
var grid_chart = this;
data = grid_chart.serializeData(data);
// calibrate axes
grid_chart.y_scale.domain(data.months);
grid_chart.svg.select(".d3-chart-range")
.call(grid_chart.y_axis);
grid_chart.x_scale.domain([1, 31]);
grid_chart.svg.select(".d3-chart-domain").call(grid_chart.x_axis);
var grid_units = grid_chart.svg.selectAll(".d3-chart-grid-unit" + series.css_class)
.data(data.series.values);
grid_chart.applyData(data.series, grid_units.enter().append("rect"));
grid_chart.applyData(data.series, grid_units.transition());
grid_units.exit().remove();
}
// helper method for drawData.
applyData(series, elements){
var grid_chart = this,
series_class = "d3-chart-grid-unit " + series.css_class;
elements
.attr("class", function(d){ return series_class + " " + d.css_class; })
.attr("y", function(d) { return grid_chart.y_scale(grid_chart.monthFormat(d[grid_chart.date_attr])); })
.attr("height", grid_chart.y_scale.rangeBand())
.attr("x", function(d) { return d[grid_chart.date_attr].getDate(); })
.attr("width", function(d) { return grid_chart.x_scale.rangeBand(); })
.attr("opacity", function(d) { return grid_chart.applyOpacity(d[grid_chart.range_attr], series.range); })
}
applyOpacity(value, range){
return (value - range.max) / range.diff;
};
}
export default CalendarGridChart;