add d3 calendar grid
This commit is contained in:
2
client/d3/bar/base.js
vendored
2
client/d3/bar/base.js
vendored
@@ -29,7 +29,7 @@ class BarChart {
|
|||||||
|
|
||||||
constructor(options){
|
constructor(options){
|
||||||
var bar_chart = this;
|
var bar_chart = this;
|
||||||
bar_chart = extend(bar_chart, DEFAULTS, options);
|
bar_chart = extend(bar_chart, DEFAULTS, bar_chart.chart_options, options);
|
||||||
|
|
||||||
bar_chart.height = bar_chart.outer_height - bar_chart.margin.top - bar_chart.margin.bottom;
|
bar_chart.height = bar_chart.outer_height - bar_chart.margin.top - bar_chart.margin.bottom;
|
||||||
bar_chart.width = bar_chart.outer_width - bar_chart.margin.left - bar_chart.margin.right;
|
bar_chart.width = bar_chart.outer_width - bar_chart.margin.left - bar_chart.margin.right;
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
base.d3.js
|
|
||||||
47
client/d3/base.js
vendored
Normal file
47
client/d3/base.js
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
const DEFAULTS = {
|
||||||
|
outer_width: 500,
|
||||||
|
outer_height: 300,
|
||||||
|
margin: {top: 0, left: 70, bottom: 50, right: 20},
|
||||||
|
domain_ticks: 10,
|
||||||
|
range_ticks: 8,
|
||||||
|
container: "container",
|
||||||
|
time_series: false,
|
||||||
|
range_label: undefined,
|
||||||
|
domain_attr: undefined,
|
||||||
|
range_attr: undefined,
|
||||||
|
titleize: function(series, datum){
|
||||||
|
var s = datum ? datum.name : series.name,
|
||||||
|
words = s.split(' '),
|
||||||
|
array = [];
|
||||||
|
for (var i=0; i<words.length; ++i) {
|
||||||
|
array.push(words[i].charAt(0).toUpperCase() + words[i].toLowerCase().slice(1));
|
||||||
|
}
|
||||||
|
return array.join(' ');
|
||||||
|
},
|
||||||
|
toClass: function(series){
|
||||||
|
return series ? series.title.toLowerCase().replace(/\s+/g, '-') : "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Chart {
|
||||||
|
|
||||||
|
constructor(options){
|
||||||
|
var chart = this;
|
||||||
|
chart = extend(chart, chart.constructor.DEFAULTS, options);
|
||||||
|
|
||||||
|
chart.height = chart.outer_height - chart.margin.top - chart.margin.bottom;
|
||||||
|
chart.width = chart.outer_width - chart.margin.left - chart.margin.right;
|
||||||
|
|
||||||
|
chart.svg = d3.select(chart.container).append("svg")
|
||||||
|
.attr("width", chart.outer_width)
|
||||||
|
.attr("height", chart.outer_height)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", "translate(" + chart.margin.left + "," + chart.margin.top + ")");
|
||||||
|
chart.defineAxes();
|
||||||
|
if (chart.afterAxes) chart.afterAxes();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Chart;
|
||||||
@@ -1 +0,0 @@
|
|||||||
composite.d3.js
|
|
||||||
122
client/d3/grid/calendar_grid.js
vendored
Normal file
122
client/d3/grid/calendar_grid.js
vendored
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
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;
|
||||||
@@ -1 +0,0 @@
|
|||||||
line.d3.js
|
|
||||||
8
client/d3/line/line.js
vendored
8
client/d3/line/line.js
vendored
@@ -38,6 +38,12 @@ class LineChart {
|
|||||||
line_chart.init();
|
line_chart.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get chart_options(){
|
||||||
|
return {
|
||||||
|
interpolation: 'basis'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
init(){
|
init(){
|
||||||
var line_chart = this;
|
var line_chart = this;
|
||||||
|
|
||||||
@@ -49,7 +55,7 @@ class LineChart {
|
|||||||
|
|
||||||
// function that draws the lines.
|
// function that draws the lines.
|
||||||
line_chart.line = d3.svg.line()
|
line_chart.line = d3.svg.line()
|
||||||
.interpolate("basis")
|
.interpolate(line_chart.chart_options.interpolation)
|
||||||
.x(function(d){ return x(d[line_chart.domain_attr]); })
|
.x(function(d){ return x(d[line_chart.domain_attr]); })
|
||||||
.y(function(d){ return y(d[line_chart.range_attr]); });
|
.y(function(d){ return y(d[line_chart.range_attr]); });
|
||||||
|
|
||||||
|
|||||||
7
client/d3/line/spline.js
vendored
7
client/d3/line/spline.js
vendored
@@ -1,6 +1,13 @@
|
|||||||
import LineChart from './line';
|
import LineChart from './line';
|
||||||
|
|
||||||
|
const INTEPOLATION = 'cardinal';
|
||||||
|
|
||||||
class SplineChart extends LineChart {
|
class SplineChart extends LineChart {
|
||||||
|
|
||||||
|
get chart_options(){
|
||||||
|
return {
|
||||||
|
interpolation: INTEPOLATION
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
pie.d3.js
|
|
||||||
Reference in New Issue
Block a user