[major] more modules: date-utils, intervals

This commit is contained in:
pratu16x7 2017-11-09 03:02:13 +05:30
parent e153c35179
commit 0f0e371006
12 changed files with 838 additions and 935 deletions

View File

@ -493,6 +493,69 @@ var UnitRenderer = function () {
return UnitRenderer;
}();
function make_x_line(height, text_start_at, point, label_class, axis_line_class, x_pos) {
var line = $.createSVG('line', {
x1: 0,
x2: 0,
y1: 0,
y2: height
});
var text = $.createSVG('text', {
className: label_class,
x: 0,
y: text_start_at,
dy: '.71em',
innerHTML: point
});
var x_line = $.createSVG('g', {
className: 'tick ' + axis_line_class,
transform: 'translate(' + x_pos + ', 0)'
});
x_line.appendChild(line);
x_line.appendChild(text);
return x_line;
}
function make_y_line(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos) {
var darker = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
var line_type = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : "";
var line = $.createSVG('line', {
className: line_type === "dashed" ? "dashed" : "",
x1: start_at,
x2: width,
y1: 0,
y2: 0
});
var text = $.createSVG('text', {
className: label_class,
x: text_end_at,
y: 0,
dy: '.32em',
innerHTML: point + ""
});
var y_line = $.createSVG('g', {
className: 'tick ' + axis_line_class,
transform: 'translate(0, ' + y_pos + ')',
'stroke-opacity': 1
});
if (darker) {
line.style.stroke = "rgba(27, 31, 35, 0.6)";
}
y_line.appendChild(line);
y_line.appendChild(text);
return y_line;
}
// Leveraging SMIL Animations
var EASING = {
@ -608,6 +671,141 @@ function runSVGAnimation(svg_container, elements) {
return anim_svg;
}
// export function calc_intervals() {
// //
// }
function calc_y_intervals(array) {
//*** Where the magic happens ***
// Calculates best-fit y intervals from given values
// and returns the interval array
// TODO: Fractions
var max_bound = void 0,
min_bound = void 0,
pos_no_of_parts = void 0,
neg_no_of_parts = void 0,
part_size = void 0; // eslint-disable-line no-unused-vars
// Critical values
var max_val = parseInt(Math.max.apply(Math, toConsumableArray(array)));
var min_val = parseInt(Math.min.apply(Math, toConsumableArray(array)));
if (min_val >= 0) {
min_val = 0;
}
var get_params = function get_params(value1, value2) {
var bound1 = void 0,
bound2 = void 0,
no_of_parts_1 = void 0,
no_of_parts_2 = void 0,
interval_size = void 0;
if ((value1 + "").length <= 1) {
bound1 = 10;
no_of_parts_1 = 5;
} else {
var _calc_upper_bound_and = calc_upper_bound_and_no_of_parts(value1);
var _calc_upper_bound_and2 = slicedToArray(_calc_upper_bound_and, 2);
bound1 = _calc_upper_bound_and2[0];
no_of_parts_1 = _calc_upper_bound_and2[1];
}
interval_size = bound1 / no_of_parts_1;
no_of_parts_2 = calc_no_of_parts(value2, interval_size);
bound2 = no_of_parts_2 * interval_size;
return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
};
var abs_min_val = min_val * -1;
if (abs_min_val <= max_val) {
var _get_params = get_params(max_val, abs_min_val);
// Get the positive region intervals
// then calc negative ones accordingly
var _get_params2 = slicedToArray(_get_params, 5);
min_bound = _get_params2[1];
pos_no_of_parts = _get_params2[2];
neg_no_of_parts = _get_params2[3];
part_size = _get_params2[4];
if (abs_min_val === 0) {
min_bound = 0;neg_no_of_parts = 0;
}
} else {
var _get_params3 = get_params(abs_min_val, max_val);
// Get the negative region here first
var _get_params4 = slicedToArray(_get_params3, 5);
min_bound = _get_params4[0];
neg_no_of_parts = _get_params4[2];
pos_no_of_parts = _get_params4[3];
part_size = _get_params4[4];
}
// Make both region parts even
if (pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
if (neg_no_of_parts % 2 !== 0) {
// every increase in no_of_parts entails an increase in corresponding bound
// except here, it happens implicitly after every calc_no_of_parts() call
neg_no_of_parts++;
min_bound += part_size;
}
var no_of_parts = pos_no_of_parts + neg_no_of_parts;
if (no_of_parts > 5) {
no_of_parts /= 2;
part_size *= 2;
pos_no_of_parts /= 2;
}
if (max_val < (pos_no_of_parts - 1) * part_size) {
no_of_parts--;
}
return get_intervals(-1 * min_bound, part_size, no_of_parts);
}
function get_intervals(start, interval_size, count) {
var intervals = [];
for (var i = 0; i <= count; i++) {
intervals.push(start);
start += interval_size;
}
return intervals;
}
function calc_upper_bound_and_no_of_parts(max_val) {
// Given a positive value, calculates a nice-number upper bound
// and a consequent optimal number of parts
var part_size = Math.pow(10, (max_val + "").length - 1);
var no_of_parts = calc_no_of_parts(max_val, part_size);
// Use it to get a nice even upper bound
var upper_bound = part_size * no_of_parts;
return [upper_bound, no_of_parts];
}
function calc_no_of_parts(value, divisor) {
// value should be a positive number, divisor should be greater than 0
// returns an even no of parts
var no_of_parts = Math.ceil(value / divisor);
if (no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
return no_of_parts;
}
/**
* Returns the value of a number upto 2 decimal places.
* @param {Number} d Any number
@ -786,6 +984,8 @@ var BaseChart = function () {
title = _ref$title === undefined ? '' : _ref$title,
_ref$subtitle = _ref.subtitle,
subtitle = _ref$subtitle === undefined ? '' : _ref$subtitle,
_ref$colors = _ref.colors,
colors = _ref$colors === undefined ? [] : _ref$colors,
_ref$format_lambdas = _ref.format_lambdas,
format_lambdas = _ref$format_lambdas === undefined ? {} : _ref$format_lambdas,
_ref$summary = _ref.summary,
@ -818,6 +1018,11 @@ var BaseChart = function () {
}
this.has_legend = has_legend;
this.colors = colors;
if (!this.colors || this.data.labels && this.colors.length < this.data.labels.length) {
this.colors = ['light-blue', 'blue', 'violet', 'red', 'orange', 'yellow', 'green', 'light-green', 'purple', 'magenta'];
}
this.chart_types = ['line', 'scatter', 'bar', 'percentage', 'heatmap', 'pie'];
this.set_margins(height);
@ -1109,8 +1314,6 @@ var AxisChart = function (_BaseChart) {
_this.get_y_tooltip = _this.format_lambdas.y_tooltip;
_this.get_x_tooltip = _this.format_lambdas.x_tooltip;
_this.colors = ['green', 'blue', 'violet', 'red', 'orange', 'yellow', 'light-blue', 'light-green', 'purple', 'magenta'];
_this.zero_line = _this.height;
_this.old_values = {};
@ -1159,7 +1362,7 @@ var AxisChart = function (_BaseChart) {
values = values.concat(this.y_sums);
}
this.y_axis_values = this.get_y_axis_points(values);
this.y_axis_values = calc_y_intervals(values);
if (!this.y_old_axis_values) {
this.y_old_axis_values = this.y_axis_values.slice();
@ -1279,7 +1482,7 @@ var AxisChart = function (_BaseChart) {
point = point.slice(0, allowed_letters - 3) + " ...";
}
}
_this4.x_axis_group.appendChild(_this4.make_x_line(height, text_start_at, point, 'x-value-text', axis_line_class, _this4.x_axis_positions[i]));
_this4.x_axis_group.appendChild(make_x_line(height, text_start_at, point, 'x-value-text', axis_line_class, _this4.x_axis_positions[i]));
});
}
@ -1307,7 +1510,7 @@ var AxisChart = function (_BaseChart) {
this.y_axis_group.textContent = '';
this.y_axis_values.map(function (value, i) {
_this5.y_axis_group.appendChild(_this5.make_y_line(start_at, width, text_end_at, value, 'y-value-text', axis_line_class, _this5.zero_line - value * _this5.multiplier, value === 0 && i !== 0 // Non-first Zero line
_this5.y_axis_group.appendChild(make_y_line(start_at, width, text_end_at, value, 'y-value-text', axis_line_class, _this5.zero_line - value * _this5.multiplier, value === 0 && i !== 0 // Non-first Zero line
));
});
}
@ -1403,7 +1606,6 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_new_units_for_dataset',
value: function make_new_units_for_dataset(x_values, y_values, color, dataset_index, no_of_datasets, units_group, units_array, unit) {
var _this9 = this;
if (!units_group) units_group = this.svg_units_groups[dataset_index];
if (!units_array) units_array = this.y[dataset_index].svg_units;
@ -1412,8 +1614,10 @@ var AxisChart = function (_BaseChart) {
units_group.textContent = '';
units_array.length = 0;
var unit_renderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
y_values.map(function (y, i) {
var data_unit = _this9.UnitRenderer['draw_' + unit.type](x_values[i], y, unit.args, color, i, dataset_index, no_of_datasets);
var data_unit = unit_renderer['draw_' + unit.type](x_values[i], y, unit.args, color, i, dataset_index, no_of_datasets);
units_group.appendChild(data_unit);
units_array.push(data_unit);
});
@ -1425,35 +1629,35 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_y_specifics',
value: function make_y_specifics() {
var _this10 = this;
var _this9 = this;
this.specific_y_group.textContent = '';
this.specific_values.map(function (d) {
_this10.specific_y_group.appendChild(_this10.make_y_line(0, _this10.width, _this10.width + 5, d.title.toUpperCase(), 'specific-value', 'specific-value', _this10.zero_line - d.value * _this10.multiplier, false, d.line_type));
_this9.specific_y_group.appendChild(make_y_line(0, _this9.width, _this9.width + 5, d.title.toUpperCase(), 'specific-value', 'specific-value', _this9.zero_line - d.value * _this9.multiplier, false, d.line_type));
});
}
}, {
key: 'bind_tooltip',
value: function bind_tooltip() {
var _this11 = this;
var _this10 = this;
// TODO: could be in tooltip itself, as it is a given functionality for its parent
this.chart_wrapper.addEventListener('mousemove', function (e) {
var offset = $.offset(_this11.chart_wrapper);
var relX = e.pageX - offset.left - _this11.translate_x;
var relY = e.pageY - offset.top - _this11.translate_y;
var offset = $.offset(_this10.chart_wrapper);
var relX = e.pageX - offset.left - _this10.translate_x;
var relY = e.pageY - offset.top - _this10.translate_y;
if (relY < _this11.height + _this11.translate_y * 2) {
_this11.map_tooltip_x_position_and_show(relX);
if (relY < _this10.height + _this10.translate_y * 2) {
_this10.map_tooltip_x_position_and_show(relX);
} else {
_this11.tip.hide_tip();
_this10.tip.hide_tip();
}
});
}
}, {
key: 'map_tooltip_x_position_and_show',
value: function map_tooltip_x_position_and_show(relX) {
var _this12 = this;
var _this11 = this;
if (!this.y_min_tops) return;
for (var i = this.x_axis_positions.length - 1; i >= 0; i--) {
@ -1468,7 +1672,7 @@ var AxisChart = function (_BaseChart) {
return {
title: set$$1.title,
value: set$$1.formatted ? set$$1.formatted[i] : set$$1.values[i],
color: set$$1.color || _this12.colors[j]
color: set$$1.color || _this11.colors[j]
};
});
@ -1485,14 +1689,14 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'show_sums',
value: function show_sums() {
var _this13 = this;
var _this12 = this;
this.updating = true;
this.y_sums = new Array(this.x_axis_positions.length).fill(0);
this.y.map(function (d) {
d.values.map(function (value, i) {
_this13.y_sums[i] += value;
_this12.y_sums[i] += value;
});
});
@ -1503,7 +1707,7 @@ var AxisChart = function (_BaseChart) {
this.sum_units = [];
this.make_new_units_for_dataset(this.x_axis_positions, this.y_sums.map(function (val) {
return float_2(_this13.zero_line - val * _this13.multiplier);
return float_2(_this12.zero_line - val * _this12.multiplier);
}), 'light-grey', 0, 1, this.sum_group, this.sum_units);
// this.make_path && this.make_path(d, i, old_x, old_y, d.color || this.colors[i]);
@ -1522,7 +1726,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'show_averages',
value: function show_averages() {
var _this14 = this;
var _this13 = this;
this.old_specific_values = this.specific_values.slice();
this.y.map(function (d, i) {
@ -1532,7 +1736,7 @@ var AxisChart = function (_BaseChart) {
});
var average = sum / d.values.length;
_this14.specific_values.push({
_this13.specific_values.push({
title: "AVG" + " " + (i + 1),
line_type: "dashed",
value: average,
@ -1545,7 +1749,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'hide_averages',
value: function hide_averages() {
var _this15 = this;
var _this14 = this;
this.old_specific_values = this.specific_values.slice();
@ -1555,7 +1759,7 @@ var AxisChart = function (_BaseChart) {
});
indices_to_remove.map(function (index) {
_this15.specific_values.splice(index, 1);
_this14.specific_values.splice(index, 1);
});
this.update_values();
@ -1563,7 +1767,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'update_values',
value: function update_values(new_y, new_x) {
var _this16 = this;
var _this15 = this;
if (!new_x) {
new_x = this.x;
@ -1595,7 +1799,7 @@ var AxisChart = function (_BaseChart) {
if (!arrays_equal(this.x_old_axis_positions, this.x_axis_positions)) {
this.make_x_axis(true);
setTimeout(function () {
if (!_this16.updating) _this16.make_x_axis();
if (!_this15.updating) _this15.make_x_axis();
}, 350);
}
@ -1603,9 +1807,9 @@ var AxisChart = function (_BaseChart) {
this.make_y_axis(true);
setTimeout(function () {
if (!_this16.updating) {
_this16.make_y_axis();
_this16.make_y_specifics();
if (!_this15.updating) {
_this15.make_y_axis();
_this15.make_y_specifics();
}
}, 350);
}
@ -1657,7 +1861,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'run_animation',
value: function run_animation() {
var _this17 = this;
var _this16 = this;
var anim_svg = runSVGAnimation(this.svg, this.elements_to_animate);
@ -1668,39 +1872,39 @@ var AxisChart = function (_BaseChart) {
// Replace the new svg (data has long been replaced)
setTimeout(function () {
if (anim_svg.parentNode == _this17.chart_wrapper) {
_this17.chart_wrapper.removeChild(anim_svg);
_this17.chart_wrapper.appendChild(_this17.svg);
if (anim_svg.parentNode == _this16.chart_wrapper) {
_this16.chart_wrapper.removeChild(anim_svg);
_this16.chart_wrapper.appendChild(_this16.svg);
}
}, 250);
}
}, {
key: 'animate_graphs',
value: function animate_graphs() {
var _this18 = this;
var _this17 = this;
this.y.map(function (d, i) {
// Pre-prep, equilize no of positions between old and new
var _calc_old_and_new_pos = _this18.calc_old_and_new_postions(d, i),
var _calc_old_and_new_pos = _this17.calc_old_and_new_postions(d, i),
_calc_old_and_new_pos2 = slicedToArray(_calc_old_and_new_pos, 4),
old_x = _calc_old_and_new_pos2[0],
old_y = _calc_old_and_new_pos2[1],
new_x = _calc_old_and_new_pos2[2],
new_y = _calc_old_and_new_pos2[3];
if (_this18.no_of_extra_pts >= 0) {
_this18.make_path && _this18.make_path(d, i, old_x, old_y, d.color || _this18.colors[i]);
_this18.make_new_units_for_dataset(old_x, old_y, d.color || _this18.colors[i], i, _this18.y.length);
if (_this17.no_of_extra_pts >= 0) {
_this17.make_path && _this17.make_path(d, i, old_x, old_y, d.color || _this17.colors[i]);
_this17.make_new_units_for_dataset(old_x, old_y, d.color || _this17.colors[i], i, _this17.y.length);
}
d.path && _this18.animate_path(d, i, old_x, old_y, new_x, new_y);
_this18.animate_units(d, i, old_x, old_y, new_x, new_y);
d.path && _this17.animate_path(d, i, old_x, old_y, new_x, new_y);
_this17.animate_units(d, i, old_x, old_y, new_x, new_y);
});
// TODO: replace with real units
setTimeout(function () {
_this18.y.map(function (d, i) {
_this18.make_path && _this18.make_path(d, i, _this18.x_axis_positions, d.y_tops, d.color || _this18.colors[i]);
_this18.make_new_units(d, i);
_this17.y.map(function (d, i) {
_this17.make_path && _this17.make_path(d, i, _this17.x_axis_positions, d.y_tops, d.color || _this17.colors[i]);
_this17.make_new_units(d, i);
});
}, 400);
}
@ -1728,14 +1932,15 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'animate_units',
value: function animate_units(d, index, old_x, old_y, new_x, new_y) {
var _this19 = this;
var _this18 = this;
var type = this.unit_args.type;
var unit_renderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
d.svg_units.map(function (unit, i) {
if (new_x[i] === undefined || new_y[i] === undefined) return;
_this19.elements_to_animate.push(_this19.UnitRenderer['animate_' + type]({ unit: unit, array: d.svg_units, index: i }, // unit, with info to replace where it came from in the data
new_x[i], new_y[i], index, _this19.y.length));
_this18.elements_to_animate.push(unit_renderer['animate_' + type]({ unit: unit, array: d.svg_units, index: i }, // unit, with info to replace where it came from in the data
new_x[i], new_y[i], index, _this18.y.length));
});
}
}, {
@ -1780,7 +1985,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_anim_x_axis',
value: function make_anim_x_axis(height, text_start_at, axis_line_class) {
var _this20 = this;
var _this19 = this;
// Animate X AXIS to account for more or less axis lines
@ -1796,12 +2001,12 @@ var AxisChart = function (_BaseChart) {
if (typeof new_pos === 'string') {
new_pos = parseInt(new_pos.substring(0, new_pos.length - 1));
}
var x_line = _this20.make_x_line(height, text_start_at, value, // new value
var x_line = make_x_line(height, text_start_at, value, // new value
'x-value-text', axis_line_class, old_pos // old position
);
_this20.x_axis_group.appendChild(x_line);
_this19.x_axis_group.appendChild(x_line);
_this20.elements_to_animate && _this20.elements_to_animate.push([{ unit: x_line, array: [0], index: 0 }, { transform: new_pos + ', 0' }, 350, "easein", "translate", { transform: old_pos + ', 0' }]);
_this19.elements_to_animate && _this19.elements_to_animate.push([{ unit: x_line, array: [0], index: 0 }, { transform: new_pos + ', 0' }, 350, "easein", "translate", { transform: old_pos + ', 0' }]);
};
this.x_axis_group.textContent = '';
@ -1811,15 +2016,15 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_anim_y_axis',
value: function make_anim_y_axis() {
var _this21 = this;
var _this20 = this;
// Animate Y AXIS to account for more or less axis lines
var old_pos = this.y_old_axis_values.map(function (value) {
return _this21.zero_line - value * _this21.multiplier;
return _this20.zero_line - value * _this20.multiplier;
});
var new_pos = this.y_axis_values.map(function (value) {
return _this21.zero_line - value * _this21.multiplier;
return _this20.zero_line - value * _this20.multiplier;
});
var old_vals = this.y_old_axis_values;
@ -1834,11 +2039,11 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_anim_y_specifics',
value: function make_anim_y_specifics() {
var _this22 = this;
var _this21 = this;
this.specific_y_group.textContent = '';
this.specific_values.map(function (d) {
_this22.add_and_animate_y_line(d.title, _this22.old_zero_line - d.value * _this22.old_multiplier, _this22.zero_line - d.value * _this22.multiplier, 0, _this22.specific_y_group, d.line_type, true);
_this21.add_and_animate_y_line(d.title, _this21.old_zero_line - d.value * _this21.old_multiplier, _this21.zero_line - d.value * _this21.multiplier, 0, _this21.specific_y_group, d.line_type, true);
});
}
}, {
@ -1879,71 +2084,6 @@ var AxisChart = function (_BaseChart) {
});
}
}
}, {
key: 'make_x_line',
value: function make_x_line$$1(height, text_start_at, point, label_class, axis_line_class, x_pos) {
var line = $.createSVG('line', {
x1: 0,
x2: 0,
y1: 0,
y2: height
});
var text = $.createSVG('text', {
className: label_class,
x: 0,
y: text_start_at,
dy: '.71em',
innerHTML: point
});
var x_level = $.createSVG('g', {
className: 'tick ' + axis_line_class,
transform: 'translate(' + x_pos + ', 0)'
});
x_level.appendChild(line);
x_level.appendChild(text);
return x_level;
}
}, {
key: 'make_y_line',
value: function make_y_line$$1(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos) {
var darker = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
var line_type = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : "";
var line = $.createSVG('line', {
className: line_type === "dashed" ? "dashed" : "",
x1: start_at,
x2: width,
y1: 0,
y2: 0
});
var text = $.createSVG('text', {
className: label_class,
x: text_end_at,
y: 0,
dy: '.32em',
innerHTML: point + ""
});
var y_level = $.createSVG('g', {
className: 'tick ' + axis_line_class,
transform: 'translate(0, ' + y_pos + ')',
'stroke-opacity': 1
});
if (darker) {
line.style.stroke = "rgba(27, 31, 35, 0.6)";
}
y_level.appendChild(line);
y_level.appendChild(text);
return y_level;
}
}, {
key: 'add_and_animate_y_line',
value: function add_and_animate_y_line(value, old_pos, new_pos, i, group, type) {
@ -1971,7 +2111,7 @@ var AxisChart = function (_BaseChart) {
var axis_label_class = !specific ? 'y-value-text' : 'specific-value';
value = !specific ? value : (value + "").toUpperCase();
var y_line = this.make_y_line(start_at, width, text_end_at, value, axis_label_class, axis_line_class, old_pos, // old position
var y_line = make_y_line(start_at, width, text_end_at, value, axis_label_class, axis_line_class, old_pos, // old position
value === 0 && i !== 0, // Non-first Zero line
type);
@ -1979,149 +2119,6 @@ var AxisChart = function (_BaseChart) {
this.elements_to_animate && this.elements_to_animate.push([{ unit: y_line, array: [0], index: 0 }, new_props, 350, "easein", "translate", old_props]);
}
}, {
key: 'get_y_axis_points',
value: function get_y_axis_points(array) {
var _this23 = this;
//*** Where the magic happens ***
// Calculates best-fit y intervals from given values
// and returns the interval array
// TODO: Fractions
var max_bound = void 0,
min_bound = void 0,
pos_no_of_parts = void 0,
neg_no_of_parts = void 0,
part_size = void 0; // eslint-disable-line no-unused-vars
// Critical values
var max_val = parseInt(Math.max.apply(Math, toConsumableArray(array)));
var min_val = parseInt(Math.min.apply(Math, toConsumableArray(array)));
if (min_val >= 0) {
min_val = 0;
}
var get_params = function get_params(value1, value2) {
var bound1 = void 0,
bound2 = void 0,
no_of_parts_1 = void 0,
no_of_parts_2 = void 0,
interval_size = void 0;
if ((value1 + "").length <= 1) {
bound1 = 10;
no_of_parts_1 = 5;
} else {
var _calc_upper_bound_and = _this23.calc_upper_bound_and_no_of_parts(value1);
var _calc_upper_bound_and2 = slicedToArray(_calc_upper_bound_and, 2);
bound1 = _calc_upper_bound_and2[0];
no_of_parts_1 = _calc_upper_bound_and2[1];
}
interval_size = bound1 / no_of_parts_1;
no_of_parts_2 = _this23.calc_no_of_parts(value2, interval_size);
bound2 = no_of_parts_2 * interval_size;
return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
};
var abs_min_val = min_val * -1;
if (abs_min_val <= max_val) {
var _get_params = get_params(max_val, abs_min_val);
// Get the positive region intervals
// then calc negative ones accordingly
var _get_params2 = slicedToArray(_get_params, 5);
min_bound = _get_params2[1];
pos_no_of_parts = _get_params2[2];
neg_no_of_parts = _get_params2[3];
part_size = _get_params2[4];
if (abs_min_val === 0) {
min_bound = 0;neg_no_of_parts = 0;
}
} else {
var _get_params3 = get_params(abs_min_val, max_val);
// Get the negative region here first
var _get_params4 = slicedToArray(_get_params3, 5);
min_bound = _get_params4[0];
neg_no_of_parts = _get_params4[2];
pos_no_of_parts = _get_params4[3];
part_size = _get_params4[4];
}
// Make both region parts even
if (pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
if (neg_no_of_parts % 2 !== 0) {
// every increase in no_of_parts entails an increase in corresponding bound
// except here, it happens implicitly after every calc_no_of_parts() call
neg_no_of_parts++;
min_bound += part_size;
}
var no_of_parts = pos_no_of_parts + neg_no_of_parts;
if (no_of_parts > 5) {
no_of_parts /= 2;
part_size *= 2;
pos_no_of_parts /= 2;
}
if (max_val < (pos_no_of_parts - 1) * part_size) {
no_of_parts--;
}
return this.get_intervals(-1 * min_bound, part_size, no_of_parts);
}
}, {
key: 'get_intervals',
value: function get_intervals(start, interval_size, count) {
var intervals = [];
for (var i = 0; i <= count; i++) {
intervals.push(start);
start += interval_size;
}
return intervals;
}
}, {
key: 'calc_upper_bound_and_no_of_parts',
value: function calc_upper_bound_and_no_of_parts(max_val) {
// Given a positive value, calculates a nice-number upper bound
// and a consequent optimal number of parts
var part_size = Math.pow(10, (max_val + "").length - 1);
var no_of_parts = this.calc_no_of_parts(max_val, part_size);
// Use it to get a nice even upper bound
var upper_bound = part_size * no_of_parts;
return [upper_bound, no_of_parts];
}
}, {
key: 'calc_no_of_parts',
value: function calc_no_of_parts(value, divisor) {
// value should be a positive number, divisor should be greater than 0
// returns an even no of parts
var no_of_parts = Math.ceil(value / divisor);
if (no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
return no_of_parts;
}
}, {
key: 'get_optimal_no_of_parts',
value: function get_optimal_no_of_parts(no_of_parts) {
// aka Divide by 2 if too large
return no_of_parts < 5 ? no_of_parts : no_of_parts / 2;
}
}, {
key: 'set_avg_unit_width_and_x_offset',
value: function set_avg_unit_width_and_x_offset() {
@ -2147,27 +2144,22 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'calc_y_dependencies',
value: function calc_y_dependencies() {
var _this24 = this;
var _this22 = this;
this.y_min_tops = new Array(this.x_axis_positions.length).fill(9999);
this.y.map(function (d) {
d.y_tops = d.values.map(function (val) {
return float_2(_this24.zero_line - val * _this24.multiplier);
return float_2(_this22.zero_line - val * _this22.multiplier);
});
d.y_tops.map(function (y_top, i) {
if (y_top < _this24.y_min_tops[i]) {
_this24.y_min_tops[i] = y_top;
if (y_top < _this22.y_min_tops[i]) {
_this22.y_min_tops[i] = y_top;
}
});
});
// this.chart_wrapper.removeChild(this.tip.container);
// this.make_tooltip();
}
}, {
key: 'setup_utils',
value: function setup_utils() {
this.UnitRenderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
}
}]);
return AxisChart;
}(BaseChart);
@ -2492,12 +2484,6 @@ var PercentageChart = function (_BaseChart) {
_this.max_slices = 10;
_this.max_legend_points = 6;
_this.colors = args.colors;
if (!_this.colors || _this.colors.length < _this.data.labels.length) {
_this.colors = ['light-blue', 'blue', 'violet', 'red', 'orange', 'yellow', 'green', 'light-green', 'purple', 'magenta'];
}
_this.setup();
return _this;
}
@ -2577,9 +2563,6 @@ var PercentageChart = function (_BaseChart) {
this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
}
}, {
key: 'setup_utils',
value: function setup_utils() {}
}, {
key: 'make_graph_components',
value: function make_graph_components() {
@ -2737,9 +2720,6 @@ var PieChart = function (_BaseChart) {
this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
}
}, {
key: 'setup_utils',
value: function setup_utils() {}
}, {
key: 'makeArcPath',
value: function makeArcPath(startPosition, endPosition) {
@ -2919,6 +2899,37 @@ var PieChart = function (_BaseChart) {
return PieChart;
}(BaseChart);
// Playing around with dates
// https://stackoverflow.com/a/11252167/6495043
function treat_as_utc(date_str) {
var result = new Date(date_str);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function get_dd_mm_yyyy(date) {
var dd = date.getDate();
var mm = date.getMonth() + 1; // getMonth() is zero-based
return [(dd > 9 ? '' : '0') + dd, (mm > 9 ? '' : '0') + mm, date.getFullYear()].join('-');
}
function get_weeks_between(start_date_str, end_date_str) {
return Math.ceil(get_days_between(start_date_str, end_date_str) / 7);
}
function get_days_between(start_date_str, end_date_str) {
var milliseconds_per_day = 24 * 60 * 60 * 1000;
return (treat_as_utc(end_date_str) - treat_as_utc(start_date_str)) / milliseconds_per_day;
}
// mutates
function add_days(date, number_of_days) {
date.setDate(date.getDate() + number_of_days);
}
// export function get_month_name() {}
var Heatmap = function (_BaseChart) {
inherits(Heatmap, _BaseChart);
@ -2948,7 +2959,7 @@ var Heatmap = function (_BaseChart) {
_this.count_label = count_label;
var today = new Date();
_this.start = start || _this.add_days(today, 365);
_this.start = start || add_days(today, 365);
_this.legend_colors = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
@ -2969,12 +2980,12 @@ var Heatmap = function (_BaseChart) {
this.first_week_start = new Date(this.start.toDateString());
this.last_week_start = new Date(this.today.toDateString());
if (this.first_week_start.getDay() !== 7) {
this.add_days(this.first_week_start, -1 * this.first_week_start.getDay());
add_days(this.first_week_start, -1 * this.first_week_start.getDay());
}
if (this.last_week_start.getDay() !== 7) {
this.add_days(this.last_week_start, -1 * this.last_week_start.getDay());
add_days(this.last_week_start, -1 * this.last_week_start.getDay());
}
this.no_of_cols = this.get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
this.no_of_cols = get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
}
}, {
key: 'set_width',
@ -3040,7 +3051,7 @@ var Heatmap = function (_BaseChart) {
this.months.push(this.current_month + '');
this.month_weeks[this.current_month] = 1;
}
this.add_days(current_week_sunday, 7);
add_days(current_week_sunday, 7);
}
this.render_month_labels();
}
@ -3088,13 +3099,13 @@ var Heatmap = function (_BaseChart) {
width: square_side,
height: square_side,
fill: this.legend_colors[color_index],
'data-date': this.get_dd_mm_yyyy(current_date),
'data-date': get_dd_mm_yyyy(current_date),
'data-value': data_value,
'data-day': current_date.getDay()
});
var next_date = new Date(current_date);
this.add_days(next_date, 1);
add_days(next_date, 1);
if (next_date.getTime() > today_time) break;
if (next_date.getMonth() - current_date.getMonth()) {
@ -3220,59 +3231,10 @@ var Heatmap = function (_BaseChart) {
return d <= value;
}).length - 1;
}
// TODO: date utils, move these out
// https://stackoverflow.com/a/11252167/6495043
}, {
key: 'treat_as_utc',
value: function treat_as_utc(date_str) {
var result = new Date(date_str);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
}, {
key: 'get_dd_mm_yyyy',
value: function get_dd_mm_yyyy(date) {
var dd = date.getDate();
var mm = date.getMonth() + 1; // getMonth() is zero-based
return [(dd > 9 ? '' : '0') + dd, (mm > 9 ? '' : '0') + mm, date.getFullYear()].join('-');
}
}, {
key: 'get_weeks_between',
value: function get_weeks_between(start_date_str, end_date_str) {
return Math.ceil(this.get_days_between(start_date_str, end_date_str) / 7);
}
}, {
key: 'get_days_between',
value: function get_days_between(start_date_str, end_date_str) {
var milliseconds_per_day = 24 * 60 * 60 * 1000;
return (this.treat_as_utc(end_date_str) - this.treat_as_utc(start_date_str)) / milliseconds_per_day;
}
// mutates
}, {
key: 'add_days',
value: function add_days(date, number_of_days) {
date.setDate(date.getDate() + number_of_days);
}
}, {
key: 'get_month_name',
value: function get_month_name() {}
}]);
return Heatmap;
}(BaseChart);
// if ("development" !== 'production') {
// // Enable LiveReload
// document.write(
// '<script src="http://' + (location.host || 'localhost').split(':')[0] +
// ':35729/livereload.js?snipver=1"></' + 'script>'
// );
// }
var chartTypes = {
line: LineChart,
bar: BarChart,

View File

@ -491,6 +491,69 @@ var UnitRenderer = function () {
return UnitRenderer;
}();
function make_x_line(height, text_start_at, point, label_class, axis_line_class, x_pos) {
var line = $.createSVG('line', {
x1: 0,
x2: 0,
y1: 0,
y2: height
});
var text = $.createSVG('text', {
className: label_class,
x: 0,
y: text_start_at,
dy: '.71em',
innerHTML: point
});
var x_line = $.createSVG('g', {
className: 'tick ' + axis_line_class,
transform: 'translate(' + x_pos + ', 0)'
});
x_line.appendChild(line);
x_line.appendChild(text);
return x_line;
}
function make_y_line(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos) {
var darker = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
var line_type = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : "";
var line = $.createSVG('line', {
className: line_type === "dashed" ? "dashed" : "",
x1: start_at,
x2: width,
y1: 0,
y2: 0
});
var text = $.createSVG('text', {
className: label_class,
x: text_end_at,
y: 0,
dy: '.32em',
innerHTML: point + ""
});
var y_line = $.createSVG('g', {
className: 'tick ' + axis_line_class,
transform: 'translate(0, ' + y_pos + ')',
'stroke-opacity': 1
});
if (darker) {
line.style.stroke = "rgba(27, 31, 35, 0.6)";
}
y_line.appendChild(line);
y_line.appendChild(text);
return y_line;
}
// Leveraging SMIL Animations
var EASING = {
@ -606,6 +669,141 @@ function runSVGAnimation(svg_container, elements) {
return anim_svg;
}
// export function calc_intervals() {
// //
// }
function calc_y_intervals(array) {
//*** Where the magic happens ***
// Calculates best-fit y intervals from given values
// and returns the interval array
// TODO: Fractions
var max_bound = void 0,
min_bound = void 0,
pos_no_of_parts = void 0,
neg_no_of_parts = void 0,
part_size = void 0; // eslint-disable-line no-unused-vars
// Critical values
var max_val = parseInt(Math.max.apply(Math, toConsumableArray(array)));
var min_val = parseInt(Math.min.apply(Math, toConsumableArray(array)));
if (min_val >= 0) {
min_val = 0;
}
var get_params = function get_params(value1, value2) {
var bound1 = void 0,
bound2 = void 0,
no_of_parts_1 = void 0,
no_of_parts_2 = void 0,
interval_size = void 0;
if ((value1 + "").length <= 1) {
bound1 = 10;
no_of_parts_1 = 5;
} else {
var _calc_upper_bound_and = calc_upper_bound_and_no_of_parts(value1);
var _calc_upper_bound_and2 = slicedToArray(_calc_upper_bound_and, 2);
bound1 = _calc_upper_bound_and2[0];
no_of_parts_1 = _calc_upper_bound_and2[1];
}
interval_size = bound1 / no_of_parts_1;
no_of_parts_2 = calc_no_of_parts(value2, interval_size);
bound2 = no_of_parts_2 * interval_size;
return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
};
var abs_min_val = min_val * -1;
if (abs_min_val <= max_val) {
var _get_params = get_params(max_val, abs_min_val);
// Get the positive region intervals
// then calc negative ones accordingly
var _get_params2 = slicedToArray(_get_params, 5);
min_bound = _get_params2[1];
pos_no_of_parts = _get_params2[2];
neg_no_of_parts = _get_params2[3];
part_size = _get_params2[4];
if (abs_min_val === 0) {
min_bound = 0;neg_no_of_parts = 0;
}
} else {
var _get_params3 = get_params(abs_min_val, max_val);
// Get the negative region here first
var _get_params4 = slicedToArray(_get_params3, 5);
min_bound = _get_params4[0];
neg_no_of_parts = _get_params4[2];
pos_no_of_parts = _get_params4[3];
part_size = _get_params4[4];
}
// Make both region parts even
if (pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
if (neg_no_of_parts % 2 !== 0) {
// every increase in no_of_parts entails an increase in corresponding bound
// except here, it happens implicitly after every calc_no_of_parts() call
neg_no_of_parts++;
min_bound += part_size;
}
var no_of_parts = pos_no_of_parts + neg_no_of_parts;
if (no_of_parts > 5) {
no_of_parts /= 2;
part_size *= 2;
pos_no_of_parts /= 2;
}
if (max_val < (pos_no_of_parts - 1) * part_size) {
no_of_parts--;
}
return get_intervals(-1 * min_bound, part_size, no_of_parts);
}
function get_intervals(start, interval_size, count) {
var intervals = [];
for (var i = 0; i <= count; i++) {
intervals.push(start);
start += interval_size;
}
return intervals;
}
function calc_upper_bound_and_no_of_parts(max_val) {
// Given a positive value, calculates a nice-number upper bound
// and a consequent optimal number of parts
var part_size = Math.pow(10, (max_val + "").length - 1);
var no_of_parts = calc_no_of_parts(max_val, part_size);
// Use it to get a nice even upper bound
var upper_bound = part_size * no_of_parts;
return [upper_bound, no_of_parts];
}
function calc_no_of_parts(value, divisor) {
// value should be a positive number, divisor should be greater than 0
// returns an even no of parts
var no_of_parts = Math.ceil(value / divisor);
if (no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
return no_of_parts;
}
/**
* Returns the value of a number upto 2 decimal places.
* @param {Number} d Any number
@ -784,6 +982,8 @@ var BaseChart = function () {
title = _ref$title === undefined ? '' : _ref$title,
_ref$subtitle = _ref.subtitle,
subtitle = _ref$subtitle === undefined ? '' : _ref$subtitle,
_ref$colors = _ref.colors,
colors = _ref$colors === undefined ? [] : _ref$colors,
_ref$format_lambdas = _ref.format_lambdas,
format_lambdas = _ref$format_lambdas === undefined ? {} : _ref$format_lambdas,
_ref$summary = _ref.summary,
@ -816,6 +1016,11 @@ var BaseChart = function () {
}
this.has_legend = has_legend;
this.colors = colors;
if (!this.colors || this.data.labels && this.colors.length < this.data.labels.length) {
this.colors = ['light-blue', 'blue', 'violet', 'red', 'orange', 'yellow', 'green', 'light-green', 'purple', 'magenta'];
}
this.chart_types = ['line', 'scatter', 'bar', 'percentage', 'heatmap', 'pie'];
this.set_margins(height);
@ -1107,8 +1312,6 @@ var AxisChart = function (_BaseChart) {
_this.get_y_tooltip = _this.format_lambdas.y_tooltip;
_this.get_x_tooltip = _this.format_lambdas.x_tooltip;
_this.colors = ['green', 'blue', 'violet', 'red', 'orange', 'yellow', 'light-blue', 'light-green', 'purple', 'magenta'];
_this.zero_line = _this.height;
_this.old_values = {};
@ -1157,7 +1360,7 @@ var AxisChart = function (_BaseChart) {
values = values.concat(this.y_sums);
}
this.y_axis_values = this.get_y_axis_points(values);
this.y_axis_values = calc_y_intervals(values);
if (!this.y_old_axis_values) {
this.y_old_axis_values = this.y_axis_values.slice();
@ -1277,7 +1480,7 @@ var AxisChart = function (_BaseChart) {
point = point.slice(0, allowed_letters - 3) + " ...";
}
}
_this4.x_axis_group.appendChild(_this4.make_x_line(height, text_start_at, point, 'x-value-text', axis_line_class, _this4.x_axis_positions[i]));
_this4.x_axis_group.appendChild(make_x_line(height, text_start_at, point, 'x-value-text', axis_line_class, _this4.x_axis_positions[i]));
});
}
@ -1305,7 +1508,7 @@ var AxisChart = function (_BaseChart) {
this.y_axis_group.textContent = '';
this.y_axis_values.map(function (value, i) {
_this5.y_axis_group.appendChild(_this5.make_y_line(start_at, width, text_end_at, value, 'y-value-text', axis_line_class, _this5.zero_line - value * _this5.multiplier, value === 0 && i !== 0 // Non-first Zero line
_this5.y_axis_group.appendChild(make_y_line(start_at, width, text_end_at, value, 'y-value-text', axis_line_class, _this5.zero_line - value * _this5.multiplier, value === 0 && i !== 0 // Non-first Zero line
));
});
}
@ -1401,7 +1604,6 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_new_units_for_dataset',
value: function make_new_units_for_dataset(x_values, y_values, color, dataset_index, no_of_datasets, units_group, units_array, unit) {
var _this9 = this;
if (!units_group) units_group = this.svg_units_groups[dataset_index];
if (!units_array) units_array = this.y[dataset_index].svg_units;
@ -1410,8 +1612,10 @@ var AxisChart = function (_BaseChart) {
units_group.textContent = '';
units_array.length = 0;
var unit_renderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
y_values.map(function (y, i) {
var data_unit = _this9.UnitRenderer['draw_' + unit.type](x_values[i], y, unit.args, color, i, dataset_index, no_of_datasets);
var data_unit = unit_renderer['draw_' + unit.type](x_values[i], y, unit.args, color, i, dataset_index, no_of_datasets);
units_group.appendChild(data_unit);
units_array.push(data_unit);
});
@ -1423,35 +1627,35 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_y_specifics',
value: function make_y_specifics() {
var _this10 = this;
var _this9 = this;
this.specific_y_group.textContent = '';
this.specific_values.map(function (d) {
_this10.specific_y_group.appendChild(_this10.make_y_line(0, _this10.width, _this10.width + 5, d.title.toUpperCase(), 'specific-value', 'specific-value', _this10.zero_line - d.value * _this10.multiplier, false, d.line_type));
_this9.specific_y_group.appendChild(make_y_line(0, _this9.width, _this9.width + 5, d.title.toUpperCase(), 'specific-value', 'specific-value', _this9.zero_line - d.value * _this9.multiplier, false, d.line_type));
});
}
}, {
key: 'bind_tooltip',
value: function bind_tooltip() {
var _this11 = this;
var _this10 = this;
// TODO: could be in tooltip itself, as it is a given functionality for its parent
this.chart_wrapper.addEventListener('mousemove', function (e) {
var offset = $.offset(_this11.chart_wrapper);
var relX = e.pageX - offset.left - _this11.translate_x;
var relY = e.pageY - offset.top - _this11.translate_y;
var offset = $.offset(_this10.chart_wrapper);
var relX = e.pageX - offset.left - _this10.translate_x;
var relY = e.pageY - offset.top - _this10.translate_y;
if (relY < _this11.height + _this11.translate_y * 2) {
_this11.map_tooltip_x_position_and_show(relX);
if (relY < _this10.height + _this10.translate_y * 2) {
_this10.map_tooltip_x_position_and_show(relX);
} else {
_this11.tip.hide_tip();
_this10.tip.hide_tip();
}
});
}
}, {
key: 'map_tooltip_x_position_and_show',
value: function map_tooltip_x_position_and_show(relX) {
var _this12 = this;
var _this11 = this;
if (!this.y_min_tops) return;
for (var i = this.x_axis_positions.length - 1; i >= 0; i--) {
@ -1466,7 +1670,7 @@ var AxisChart = function (_BaseChart) {
return {
title: set$$1.title,
value: set$$1.formatted ? set$$1.formatted[i] : set$$1.values[i],
color: set$$1.color || _this12.colors[j]
color: set$$1.color || _this11.colors[j]
};
});
@ -1483,14 +1687,14 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'show_sums',
value: function show_sums() {
var _this13 = this;
var _this12 = this;
this.updating = true;
this.y_sums = new Array(this.x_axis_positions.length).fill(0);
this.y.map(function (d) {
d.values.map(function (value, i) {
_this13.y_sums[i] += value;
_this12.y_sums[i] += value;
});
});
@ -1501,7 +1705,7 @@ var AxisChart = function (_BaseChart) {
this.sum_units = [];
this.make_new_units_for_dataset(this.x_axis_positions, this.y_sums.map(function (val) {
return float_2(_this13.zero_line - val * _this13.multiplier);
return float_2(_this12.zero_line - val * _this12.multiplier);
}), 'light-grey', 0, 1, this.sum_group, this.sum_units);
// this.make_path && this.make_path(d, i, old_x, old_y, d.color || this.colors[i]);
@ -1520,7 +1724,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'show_averages',
value: function show_averages() {
var _this14 = this;
var _this13 = this;
this.old_specific_values = this.specific_values.slice();
this.y.map(function (d, i) {
@ -1530,7 +1734,7 @@ var AxisChart = function (_BaseChart) {
});
var average = sum / d.values.length;
_this14.specific_values.push({
_this13.specific_values.push({
title: "AVG" + " " + (i + 1),
line_type: "dashed",
value: average,
@ -1543,7 +1747,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'hide_averages',
value: function hide_averages() {
var _this15 = this;
var _this14 = this;
this.old_specific_values = this.specific_values.slice();
@ -1553,7 +1757,7 @@ var AxisChart = function (_BaseChart) {
});
indices_to_remove.map(function (index) {
_this15.specific_values.splice(index, 1);
_this14.specific_values.splice(index, 1);
});
this.update_values();
@ -1561,7 +1765,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'update_values',
value: function update_values(new_y, new_x) {
var _this16 = this;
var _this15 = this;
if (!new_x) {
new_x = this.x;
@ -1593,7 +1797,7 @@ var AxisChart = function (_BaseChart) {
if (!arrays_equal(this.x_old_axis_positions, this.x_axis_positions)) {
this.make_x_axis(true);
setTimeout(function () {
if (!_this16.updating) _this16.make_x_axis();
if (!_this15.updating) _this15.make_x_axis();
}, 350);
}
@ -1601,9 +1805,9 @@ var AxisChart = function (_BaseChart) {
this.make_y_axis(true);
setTimeout(function () {
if (!_this16.updating) {
_this16.make_y_axis();
_this16.make_y_specifics();
if (!_this15.updating) {
_this15.make_y_axis();
_this15.make_y_specifics();
}
}, 350);
}
@ -1655,7 +1859,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'run_animation',
value: function run_animation() {
var _this17 = this;
var _this16 = this;
var anim_svg = runSVGAnimation(this.svg, this.elements_to_animate);
@ -1666,39 +1870,39 @@ var AxisChart = function (_BaseChart) {
// Replace the new svg (data has long been replaced)
setTimeout(function () {
if (anim_svg.parentNode == _this17.chart_wrapper) {
_this17.chart_wrapper.removeChild(anim_svg);
_this17.chart_wrapper.appendChild(_this17.svg);
if (anim_svg.parentNode == _this16.chart_wrapper) {
_this16.chart_wrapper.removeChild(anim_svg);
_this16.chart_wrapper.appendChild(_this16.svg);
}
}, 250);
}
}, {
key: 'animate_graphs',
value: function animate_graphs() {
var _this18 = this;
var _this17 = this;
this.y.map(function (d, i) {
// Pre-prep, equilize no of positions between old and new
var _calc_old_and_new_pos = _this18.calc_old_and_new_postions(d, i),
var _calc_old_and_new_pos = _this17.calc_old_and_new_postions(d, i),
_calc_old_and_new_pos2 = slicedToArray(_calc_old_and_new_pos, 4),
old_x = _calc_old_and_new_pos2[0],
old_y = _calc_old_and_new_pos2[1],
new_x = _calc_old_and_new_pos2[2],
new_y = _calc_old_and_new_pos2[3];
if (_this18.no_of_extra_pts >= 0) {
_this18.make_path && _this18.make_path(d, i, old_x, old_y, d.color || _this18.colors[i]);
_this18.make_new_units_for_dataset(old_x, old_y, d.color || _this18.colors[i], i, _this18.y.length);
if (_this17.no_of_extra_pts >= 0) {
_this17.make_path && _this17.make_path(d, i, old_x, old_y, d.color || _this17.colors[i]);
_this17.make_new_units_for_dataset(old_x, old_y, d.color || _this17.colors[i], i, _this17.y.length);
}
d.path && _this18.animate_path(d, i, old_x, old_y, new_x, new_y);
_this18.animate_units(d, i, old_x, old_y, new_x, new_y);
d.path && _this17.animate_path(d, i, old_x, old_y, new_x, new_y);
_this17.animate_units(d, i, old_x, old_y, new_x, new_y);
});
// TODO: replace with real units
setTimeout(function () {
_this18.y.map(function (d, i) {
_this18.make_path && _this18.make_path(d, i, _this18.x_axis_positions, d.y_tops, d.color || _this18.colors[i]);
_this18.make_new_units(d, i);
_this17.y.map(function (d, i) {
_this17.make_path && _this17.make_path(d, i, _this17.x_axis_positions, d.y_tops, d.color || _this17.colors[i]);
_this17.make_new_units(d, i);
});
}, 400);
}
@ -1726,14 +1930,15 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'animate_units',
value: function animate_units(d, index, old_x, old_y, new_x, new_y) {
var _this19 = this;
var _this18 = this;
var type = this.unit_args.type;
var unit_renderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
d.svg_units.map(function (unit, i) {
if (new_x[i] === undefined || new_y[i] === undefined) return;
_this19.elements_to_animate.push(_this19.UnitRenderer['animate_' + type]({ unit: unit, array: d.svg_units, index: i }, // unit, with info to replace where it came from in the data
new_x[i], new_y[i], index, _this19.y.length));
_this18.elements_to_animate.push(unit_renderer['animate_' + type]({ unit: unit, array: d.svg_units, index: i }, // unit, with info to replace where it came from in the data
new_x[i], new_y[i], index, _this18.y.length));
});
}
}, {
@ -1778,7 +1983,7 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_anim_x_axis',
value: function make_anim_x_axis(height, text_start_at, axis_line_class) {
var _this20 = this;
var _this19 = this;
// Animate X AXIS to account for more or less axis lines
@ -1794,12 +1999,12 @@ var AxisChart = function (_BaseChart) {
if (typeof new_pos === 'string') {
new_pos = parseInt(new_pos.substring(0, new_pos.length - 1));
}
var x_line = _this20.make_x_line(height, text_start_at, value, // new value
var x_line = make_x_line(height, text_start_at, value, // new value
'x-value-text', axis_line_class, old_pos // old position
);
_this20.x_axis_group.appendChild(x_line);
_this19.x_axis_group.appendChild(x_line);
_this20.elements_to_animate && _this20.elements_to_animate.push([{ unit: x_line, array: [0], index: 0 }, { transform: new_pos + ', 0' }, 350, "easein", "translate", { transform: old_pos + ', 0' }]);
_this19.elements_to_animate && _this19.elements_to_animate.push([{ unit: x_line, array: [0], index: 0 }, { transform: new_pos + ', 0' }, 350, "easein", "translate", { transform: old_pos + ', 0' }]);
};
this.x_axis_group.textContent = '';
@ -1809,15 +2014,15 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_anim_y_axis',
value: function make_anim_y_axis() {
var _this21 = this;
var _this20 = this;
// Animate Y AXIS to account for more or less axis lines
var old_pos = this.y_old_axis_values.map(function (value) {
return _this21.zero_line - value * _this21.multiplier;
return _this20.zero_line - value * _this20.multiplier;
});
var new_pos = this.y_axis_values.map(function (value) {
return _this21.zero_line - value * _this21.multiplier;
return _this20.zero_line - value * _this20.multiplier;
});
var old_vals = this.y_old_axis_values;
@ -1832,11 +2037,11 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'make_anim_y_specifics',
value: function make_anim_y_specifics() {
var _this22 = this;
var _this21 = this;
this.specific_y_group.textContent = '';
this.specific_values.map(function (d) {
_this22.add_and_animate_y_line(d.title, _this22.old_zero_line - d.value * _this22.old_multiplier, _this22.zero_line - d.value * _this22.multiplier, 0, _this22.specific_y_group, d.line_type, true);
_this21.add_and_animate_y_line(d.title, _this21.old_zero_line - d.value * _this21.old_multiplier, _this21.zero_line - d.value * _this21.multiplier, 0, _this21.specific_y_group, d.line_type, true);
});
}
}, {
@ -1877,71 +2082,6 @@ var AxisChart = function (_BaseChart) {
});
}
}
}, {
key: 'make_x_line',
value: function make_x_line$$1(height, text_start_at, point, label_class, axis_line_class, x_pos) {
var line = $.createSVG('line', {
x1: 0,
x2: 0,
y1: 0,
y2: height
});
var text = $.createSVG('text', {
className: label_class,
x: 0,
y: text_start_at,
dy: '.71em',
innerHTML: point
});
var x_level = $.createSVG('g', {
className: 'tick ' + axis_line_class,
transform: 'translate(' + x_pos + ', 0)'
});
x_level.appendChild(line);
x_level.appendChild(text);
return x_level;
}
}, {
key: 'make_y_line',
value: function make_y_line$$1(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos) {
var darker = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
var line_type = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : "";
var line = $.createSVG('line', {
className: line_type === "dashed" ? "dashed" : "",
x1: start_at,
x2: width,
y1: 0,
y2: 0
});
var text = $.createSVG('text', {
className: label_class,
x: text_end_at,
y: 0,
dy: '.32em',
innerHTML: point + ""
});
var y_level = $.createSVG('g', {
className: 'tick ' + axis_line_class,
transform: 'translate(0, ' + y_pos + ')',
'stroke-opacity': 1
});
if (darker) {
line.style.stroke = "rgba(27, 31, 35, 0.6)";
}
y_level.appendChild(line);
y_level.appendChild(text);
return y_level;
}
}, {
key: 'add_and_animate_y_line',
value: function add_and_animate_y_line(value, old_pos, new_pos, i, group, type) {
@ -1969,7 +2109,7 @@ var AxisChart = function (_BaseChart) {
var axis_label_class = !specific ? 'y-value-text' : 'specific-value';
value = !specific ? value : (value + "").toUpperCase();
var y_line = this.make_y_line(start_at, width, text_end_at, value, axis_label_class, axis_line_class, old_pos, // old position
var y_line = make_y_line(start_at, width, text_end_at, value, axis_label_class, axis_line_class, old_pos, // old position
value === 0 && i !== 0, // Non-first Zero line
type);
@ -1977,149 +2117,6 @@ var AxisChart = function (_BaseChart) {
this.elements_to_animate && this.elements_to_animate.push([{ unit: y_line, array: [0], index: 0 }, new_props, 350, "easein", "translate", old_props]);
}
}, {
key: 'get_y_axis_points',
value: function get_y_axis_points(array) {
var _this23 = this;
//*** Where the magic happens ***
// Calculates best-fit y intervals from given values
// and returns the interval array
// TODO: Fractions
var max_bound = void 0,
min_bound = void 0,
pos_no_of_parts = void 0,
neg_no_of_parts = void 0,
part_size = void 0; // eslint-disable-line no-unused-vars
// Critical values
var max_val = parseInt(Math.max.apply(Math, toConsumableArray(array)));
var min_val = parseInt(Math.min.apply(Math, toConsumableArray(array)));
if (min_val >= 0) {
min_val = 0;
}
var get_params = function get_params(value1, value2) {
var bound1 = void 0,
bound2 = void 0,
no_of_parts_1 = void 0,
no_of_parts_2 = void 0,
interval_size = void 0;
if ((value1 + "").length <= 1) {
bound1 = 10;
no_of_parts_1 = 5;
} else {
var _calc_upper_bound_and = _this23.calc_upper_bound_and_no_of_parts(value1);
var _calc_upper_bound_and2 = slicedToArray(_calc_upper_bound_and, 2);
bound1 = _calc_upper_bound_and2[0];
no_of_parts_1 = _calc_upper_bound_and2[1];
}
interval_size = bound1 / no_of_parts_1;
no_of_parts_2 = _this23.calc_no_of_parts(value2, interval_size);
bound2 = no_of_parts_2 * interval_size;
return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
};
var abs_min_val = min_val * -1;
if (abs_min_val <= max_val) {
var _get_params = get_params(max_val, abs_min_val);
// Get the positive region intervals
// then calc negative ones accordingly
var _get_params2 = slicedToArray(_get_params, 5);
min_bound = _get_params2[1];
pos_no_of_parts = _get_params2[2];
neg_no_of_parts = _get_params2[3];
part_size = _get_params2[4];
if (abs_min_val === 0) {
min_bound = 0;neg_no_of_parts = 0;
}
} else {
var _get_params3 = get_params(abs_min_val, max_val);
// Get the negative region here first
var _get_params4 = slicedToArray(_get_params3, 5);
min_bound = _get_params4[0];
neg_no_of_parts = _get_params4[2];
pos_no_of_parts = _get_params4[3];
part_size = _get_params4[4];
}
// Make both region parts even
if (pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
if (neg_no_of_parts % 2 !== 0) {
// every increase in no_of_parts entails an increase in corresponding bound
// except here, it happens implicitly after every calc_no_of_parts() call
neg_no_of_parts++;
min_bound += part_size;
}
var no_of_parts = pos_no_of_parts + neg_no_of_parts;
if (no_of_parts > 5) {
no_of_parts /= 2;
part_size *= 2;
pos_no_of_parts /= 2;
}
if (max_val < (pos_no_of_parts - 1) * part_size) {
no_of_parts--;
}
return this.get_intervals(-1 * min_bound, part_size, no_of_parts);
}
}, {
key: 'get_intervals',
value: function get_intervals(start, interval_size, count) {
var intervals = [];
for (var i = 0; i <= count; i++) {
intervals.push(start);
start += interval_size;
}
return intervals;
}
}, {
key: 'calc_upper_bound_and_no_of_parts',
value: function calc_upper_bound_and_no_of_parts(max_val) {
// Given a positive value, calculates a nice-number upper bound
// and a consequent optimal number of parts
var part_size = Math.pow(10, (max_val + "").length - 1);
var no_of_parts = this.calc_no_of_parts(max_val, part_size);
// Use it to get a nice even upper bound
var upper_bound = part_size * no_of_parts;
return [upper_bound, no_of_parts];
}
}, {
key: 'calc_no_of_parts',
value: function calc_no_of_parts(value, divisor) {
// value should be a positive number, divisor should be greater than 0
// returns an even no of parts
var no_of_parts = Math.ceil(value / divisor);
if (no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
return no_of_parts;
}
}, {
key: 'get_optimal_no_of_parts',
value: function get_optimal_no_of_parts(no_of_parts) {
// aka Divide by 2 if too large
return no_of_parts < 5 ? no_of_parts : no_of_parts / 2;
}
}, {
key: 'set_avg_unit_width_and_x_offset',
value: function set_avg_unit_width_and_x_offset() {
@ -2145,27 +2142,22 @@ var AxisChart = function (_BaseChart) {
}, {
key: 'calc_y_dependencies',
value: function calc_y_dependencies() {
var _this24 = this;
var _this22 = this;
this.y_min_tops = new Array(this.x_axis_positions.length).fill(9999);
this.y.map(function (d) {
d.y_tops = d.values.map(function (val) {
return float_2(_this24.zero_line - val * _this24.multiplier);
return float_2(_this22.zero_line - val * _this22.multiplier);
});
d.y_tops.map(function (y_top, i) {
if (y_top < _this24.y_min_tops[i]) {
_this24.y_min_tops[i] = y_top;
if (y_top < _this22.y_min_tops[i]) {
_this22.y_min_tops[i] = y_top;
}
});
});
// this.chart_wrapper.removeChild(this.tip.container);
// this.make_tooltip();
}
}, {
key: 'setup_utils',
value: function setup_utils() {
this.UnitRenderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
}
}]);
return AxisChart;
}(BaseChart);
@ -2490,12 +2482,6 @@ var PercentageChart = function (_BaseChart) {
_this.max_slices = 10;
_this.max_legend_points = 6;
_this.colors = args.colors;
if (!_this.colors || _this.colors.length < _this.data.labels.length) {
_this.colors = ['light-blue', 'blue', 'violet', 'red', 'orange', 'yellow', 'green', 'light-green', 'purple', 'magenta'];
}
_this.setup();
return _this;
}
@ -2575,9 +2561,6 @@ var PercentageChart = function (_BaseChart) {
this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
}
}, {
key: 'setup_utils',
value: function setup_utils() {}
}, {
key: 'make_graph_components',
value: function make_graph_components() {
@ -2735,9 +2718,6 @@ var PieChart = function (_BaseChart) {
this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
}
}, {
key: 'setup_utils',
value: function setup_utils() {}
}, {
key: 'makeArcPath',
value: function makeArcPath(startPosition, endPosition) {
@ -2917,6 +2897,37 @@ var PieChart = function (_BaseChart) {
return PieChart;
}(BaseChart);
// Playing around with dates
// https://stackoverflow.com/a/11252167/6495043
function treat_as_utc(date_str) {
var result = new Date(date_str);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function get_dd_mm_yyyy(date) {
var dd = date.getDate();
var mm = date.getMonth() + 1; // getMonth() is zero-based
return [(dd > 9 ? '' : '0') + dd, (mm > 9 ? '' : '0') + mm, date.getFullYear()].join('-');
}
function get_weeks_between(start_date_str, end_date_str) {
return Math.ceil(get_days_between(start_date_str, end_date_str) / 7);
}
function get_days_between(start_date_str, end_date_str) {
var milliseconds_per_day = 24 * 60 * 60 * 1000;
return (treat_as_utc(end_date_str) - treat_as_utc(start_date_str)) / milliseconds_per_day;
}
// mutates
function add_days(date, number_of_days) {
date.setDate(date.getDate() + number_of_days);
}
// export function get_month_name() {}
var Heatmap = function (_BaseChart) {
inherits(Heatmap, _BaseChart);
@ -2946,7 +2957,7 @@ var Heatmap = function (_BaseChart) {
_this.count_label = count_label;
var today = new Date();
_this.start = start || _this.add_days(today, 365);
_this.start = start || add_days(today, 365);
_this.legend_colors = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
@ -2967,12 +2978,12 @@ var Heatmap = function (_BaseChart) {
this.first_week_start = new Date(this.start.toDateString());
this.last_week_start = new Date(this.today.toDateString());
if (this.first_week_start.getDay() !== 7) {
this.add_days(this.first_week_start, -1 * this.first_week_start.getDay());
add_days(this.first_week_start, -1 * this.first_week_start.getDay());
}
if (this.last_week_start.getDay() !== 7) {
this.add_days(this.last_week_start, -1 * this.last_week_start.getDay());
add_days(this.last_week_start, -1 * this.last_week_start.getDay());
}
this.no_of_cols = this.get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
this.no_of_cols = get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
}
}, {
key: 'set_width',
@ -3038,7 +3049,7 @@ var Heatmap = function (_BaseChart) {
this.months.push(this.current_month + '');
this.month_weeks[this.current_month] = 1;
}
this.add_days(current_week_sunday, 7);
add_days(current_week_sunday, 7);
}
this.render_month_labels();
}
@ -3086,13 +3097,13 @@ var Heatmap = function (_BaseChart) {
width: square_side,
height: square_side,
fill: this.legend_colors[color_index],
'data-date': this.get_dd_mm_yyyy(current_date),
'data-date': get_dd_mm_yyyy(current_date),
'data-value': data_value,
'data-day': current_date.getDay()
});
var next_date = new Date(current_date);
this.add_days(next_date, 1);
add_days(next_date, 1);
if (next_date.getTime() > today_time) break;
if (next_date.getMonth() - current_date.getMonth()) {
@ -3218,59 +3229,10 @@ var Heatmap = function (_BaseChart) {
return d <= value;
}).length - 1;
}
// TODO: date utils, move these out
// https://stackoverflow.com/a/11252167/6495043
}, {
key: 'treat_as_utc',
value: function treat_as_utc(date_str) {
var result = new Date(date_str);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
}, {
key: 'get_dd_mm_yyyy',
value: function get_dd_mm_yyyy(date) {
var dd = date.getDate();
var mm = date.getMonth() + 1; // getMonth() is zero-based
return [(dd > 9 ? '' : '0') + dd, (mm > 9 ? '' : '0') + mm, date.getFullYear()].join('-');
}
}, {
key: 'get_weeks_between',
value: function get_weeks_between(start_date_str, end_date_str) {
return Math.ceil(this.get_days_between(start_date_str, end_date_str) / 7);
}
}, {
key: 'get_days_between',
value: function get_days_between(start_date_str, end_date_str) {
var milliseconds_per_day = 24 * 60 * 60 * 1000;
return (this.treat_as_utc(end_date_str) - this.treat_as_utc(start_date_str)) / milliseconds_per_day;
}
// mutates
}, {
key: 'add_days',
value: function add_days(date, number_of_days) {
date.setDate(date.getDate() + number_of_days);
}
}, {
key: 'get_month_name',
value: function get_month_name() {}
}]);
return Heatmap;
}(BaseChart);
// if ("development" !== 'production') {
// // Enable LiveReload
// document.write(
// '<script src="http://' + (location.host || 'localhost').split(':')[0] +
// ':35729/livereload.js?snipver=1"></' + 'script>'
// );
// }
var chartTypes = {
line: LineChart,
bar: BarChart,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
import $ from '../utils/dom';
import { UnitRenderer } from '../utils/draw';
import { UnitRenderer, make_x_line, make_y_line } from '../utils/draw';
import { runSVGAnimation } from '../utils/animate';
import { calc_y_intervals } from '../utils/intervals';
import { float_2, arrays_equal, get_string_width } from '../utils/helpers';
import BaseChart from './BaseChart';
@ -17,9 +18,6 @@ export default class AxisChart extends BaseChart {
this.get_y_tooltip = this.format_lambdas.y_tooltip;
this.get_x_tooltip = this.format_lambdas.x_tooltip;
this.colors = ['green', 'blue', 'violet', 'red', 'orange',
'yellow', 'light-blue', 'light-green', 'purple', 'magenta'];
this.zero_line = this.height;
this.old_values = {};
@ -58,7 +56,7 @@ export default class AxisChart extends BaseChart {
values = values.concat(this.y_sums);
}
this.y_axis_values = this.get_y_axis_points(values);
this.y_axis_values = calc_y_intervals(values);
if(!this.y_old_axis_values) {
this.y_old_axis_values = this.y_axis_values.slice();
@ -158,7 +156,7 @@ export default class AxisChart extends BaseChart {
}
}
this.x_axis_group.appendChild(
this.make_x_line(
make_x_line(
height,
text_start_at,
point,
@ -183,7 +181,7 @@ export default class AxisChart extends BaseChart {
this.y_axis_group.textContent = '';
this.y_axis_values.map((value, i) => {
this.y_axis_group.appendChild(
this.make_y_line(
make_y_line(
start_at,
width,
text_end_at,
@ -282,8 +280,10 @@ export default class AxisChart extends BaseChart {
units_group.textContent = '';
units_array.length = 0;
let unit_renderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
y_values.map((y, i) => {
let data_unit = this.UnitRenderer['draw_' + unit.type](
let data_unit = unit_renderer['draw_' + unit.type](
x_values[i],
y,
unit.args,
@ -305,7 +305,7 @@ export default class AxisChart extends BaseChart {
this.specific_y_group.textContent = '';
this.specific_values.map(d => {
this.specific_y_group.appendChild(
this.make_y_line(
make_y_line(
0,
this.width,
this.width + 5,
@ -572,10 +572,11 @@ export default class AxisChart extends BaseChart {
animate_units(d, index, old_x, old_y, new_x, new_y) {
let type = this.unit_args.type;
let unit_renderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
d.svg_units.map((unit, i) => {
if(new_x[i] === undefined || new_y[i] === undefined) return;
this.elements_to_animate.push(this.UnitRenderer['animate_' + type](
this.elements_to_animate.push(unit_renderer['animate_' + type](
{unit:unit, array:d.svg_units, index: i}, // unit, with info to replace where it came from in the data
new_x[i],
new_y[i],
@ -639,7 +640,7 @@ export default class AxisChart extends BaseChart {
if(typeof new_pos === 'string') {
new_pos = parseInt(new_pos.substring(0, new_pos.length-1));
}
const x_line = this.make_x_line(
const x_line = make_x_line(
height,
text_start_at,
value, // new value
@ -748,66 +749,6 @@ export default class AxisChart extends BaseChart {
}
}
make_x_line(height, text_start_at, point, label_class, axis_line_class, x_pos) {
let line = $.createSVG('line', {
x1: 0,
x2: 0,
y1: 0,
y2: height
});
let text = $.createSVG('text', {
className: label_class,
x: 0,
y: text_start_at,
dy: '.71em',
innerHTML: point
});
let x_level = $.createSVG('g', {
className: `tick ${axis_line_class}`,
transform: `translate(${ x_pos }, 0)`
});
x_level.appendChild(line);
x_level.appendChild(text);
return x_level;
}
make_y_line(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos, darker=false, line_type="") {
let line = $.createSVG('line', {
className: line_type === "dashed" ? "dashed": "",
x1: start_at,
x2: width,
y1: 0,
y2: 0
});
let text = $.createSVG('text', {
className: label_class,
x: text_end_at,
y: 0,
dy: '.32em',
innerHTML: point+""
});
let y_level = $.createSVG('g', {
className: `tick ${axis_line_class}`,
transform: `translate(0, ${y_pos})`,
'stroke-opacity': 1
});
if(darker) {
line.style.stroke = "rgba(27, 31, 35, 0.6)";
}
y_level.appendChild(line);
y_level.appendChild(text);
return y_level;
}
add_and_animate_y_line(value, old_pos, new_pos, i, group, type, specific=false) {
let filler = false;
if(typeof new_pos === 'string') {
@ -825,7 +766,7 @@ export default class AxisChart extends BaseChart {
let [width, text_end_at, axis_line_class, start_at] = this.get_y_axis_line_props(specific);
let axis_label_class = !specific ? 'y-value-text' : 'specific-value';
value = !specific ? value : (value+"").toUpperCase();
const y_line = this.make_y_line(
const y_line = make_y_line(
start_at,
width,
text_end_at,
@ -849,117 +790,6 @@ export default class AxisChart extends BaseChart {
]);
}
get_y_axis_points(array) {
//*** Where the magic happens ***
// Calculates best-fit y intervals from given values
// and returns the interval array
// TODO: Fractions
let max_bound, min_bound, pos_no_of_parts, neg_no_of_parts, part_size; // eslint-disable-line no-unused-vars
// Critical values
let max_val = parseInt(Math.max(...array));
let min_val = parseInt(Math.min(...array));
if(min_val >= 0) {
min_val = 0;
}
let get_params = (value1, value2) => {
let bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size;
if((value1+"").length <= 1) {
[bound1, no_of_parts_1] = [10, 5];
} else {
[bound1, no_of_parts_1] = this.calc_upper_bound_and_no_of_parts(value1);
}
interval_size = bound1 / no_of_parts_1;
no_of_parts_2 = this.calc_no_of_parts(value2, interval_size);
bound2 = no_of_parts_2 * interval_size;
return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
};
const abs_min_val = min_val * -1;
if(abs_min_val <= max_val) {
// Get the positive region intervals
// then calc negative ones accordingly
[max_bound, min_bound, pos_no_of_parts, neg_no_of_parts, part_size]
= get_params(max_val, abs_min_val);
if(abs_min_val === 0) {
min_bound = 0; neg_no_of_parts = 0;
}
} else {
// Get the negative region here first
[min_bound, max_bound, neg_no_of_parts, pos_no_of_parts, part_size]
= get_params(abs_min_val, max_val);
}
// Make both region parts even
if(pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
if(neg_no_of_parts % 2 !== 0) {
// every increase in no_of_parts entails an increase in corresponding bound
// except here, it happens implicitly after every calc_no_of_parts() call
neg_no_of_parts++;
min_bound += part_size;
}
let no_of_parts = pos_no_of_parts + neg_no_of_parts;
if(no_of_parts > 5) {
no_of_parts /= 2;
part_size *= 2;
pos_no_of_parts /=2;
}
if (max_val < (pos_no_of_parts - 1) * part_size) {
no_of_parts--;
}
return this.get_intervals(
(-1) * min_bound,
part_size,
no_of_parts
);
}
get_intervals(start, interval_size, count) {
let intervals = [];
for(var i = 0; i <= count; i++){
intervals.push(start);
start += interval_size;
}
return intervals;
}
calc_upper_bound_and_no_of_parts(max_val) {
// Given a positive value, calculates a nice-number upper bound
// and a consequent optimal number of parts
const part_size = Math.pow(10, ((max_val+"").length - 1));
const no_of_parts = this.calc_no_of_parts(max_val, part_size);
// Use it to get a nice even upper bound
const upper_bound = part_size * no_of_parts;
return [upper_bound, no_of_parts];
}
calc_no_of_parts(value, divisor) {
// value should be a positive number, divisor should be greater than 0
// returns an even no of parts
let no_of_parts = Math.ceil(value / divisor);
if(no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
return no_of_parts;
}
get_optimal_no_of_parts(no_of_parts) {
// aka Divide by 2 if too large
return (no_of_parts < 5) ? no_of_parts : no_of_parts / 2;
}
set_avg_unit_width_and_x_offset() {
// Set the ... you get it
this.avg_unit_width = this.width/(this.x.length - 1);
@ -991,8 +821,4 @@ export default class AxisChart extends BaseChart {
// this.chart_wrapper.removeChild(this.tip.container);
// this.make_tooltip();
}
setup_utils() {
this.UnitRenderer = new UnitRenderer(this.height, this.zero_line, this.avg_unit_width);
}
}

View File

@ -7,10 +7,10 @@ export default class BaseChart {
constructor({
height = 240,
title = '', subtitle = '',
title = '',
subtitle = '',
colors = [],
format_lambdas = {},
summary = [],
is_navigable = 0,
@ -39,6 +39,12 @@ export default class BaseChart {
}
this.has_legend = has_legend;
this.colors = colors;
if(!this.colors || (this.data.labels && this.colors.length < this.data.labels.length)) {
this.colors = ['light-blue', 'blue', 'violet', 'red', 'orange',
'yellow', 'green', 'light-green', 'purple', 'magenta'];
}
this.chart_types = ['line', 'scatter', 'bar', 'percentage', 'heatmap', 'pie'];
this.set_margins(height);

View File

@ -1,5 +1,6 @@
import BaseChart from './BaseChart';
import $ from '../utils/dom';
import { add_days, get_dd_mm_yyyy, get_weeks_between } from '../utils/date-utils';
export default class Heatmap extends BaseChart {
constructor({
@ -21,7 +22,7 @@ export default class Heatmap extends BaseChart {
this.count_label = count_label;
let today = new Date();
this.start = start || this.add_days(today, 365);
this.start = start || add_days(today, 365);
this.legend_colors = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
@ -39,12 +40,12 @@ export default class Heatmap extends BaseChart {
this.first_week_start = new Date(this.start.toDateString());
this.last_week_start = new Date(this.today.toDateString());
if(this.first_week_start.getDay() !== 7) {
this.add_days(this.first_week_start, (-1) * this.first_week_start.getDay());
add_days(this.first_week_start, (-1) * this.first_week_start.getDay());
}
if(this.last_week_start.getDay() !== 7) {
this.add_days(this.last_week_start, (-1) * this.last_week_start.getDay());
add_days(this.last_week_start, (-1) * this.last_week_start.getDay());
}
this.no_of_cols = this.get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
this.no_of_cols = get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
}
set_width() {
@ -101,7 +102,7 @@ export default class Heatmap extends BaseChart {
this.months.push(this.current_month + '');
this.month_weeks[this.current_month] = 1;
}
this.add_days(current_week_sunday, 7);
add_days(current_week_sunday, 7);
}
this.render_month_labels();
}
@ -148,13 +149,13 @@ export default class Heatmap extends BaseChart {
width: square_side,
height: square_side,
fill: this.legend_colors[color_index],
'data-date': this.get_dd_mm_yyyy(current_date),
'data-date': get_dd_mm_yyyy(current_date),
'data-value': data_value,
'data-day': current_date.getDay()
});
let next_date = new Date(current_date);
this.add_days(next_date, 1);
add_days(next_date, 1);
if(next_date.getTime() > today_time) break;
@ -270,39 +271,4 @@ export default class Heatmap extends BaseChart {
return d <= value;
}).length - 1;
}
// TODO: date utils, move these out
// https://stackoverflow.com/a/11252167/6495043
treat_as_utc(date_str) {
let result = new Date(date_str);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
get_dd_mm_yyyy(date) {
let dd = date.getDate();
let mm = date.getMonth() + 1; // getMonth() is zero-based
return [
(dd>9 ? '' : '0') + dd,
(mm>9 ? '' : '0') + mm,
date.getFullYear()
].join('-');
}
get_weeks_between(start_date_str, end_date_str) {
return Math.ceil(this.get_days_between(start_date_str, end_date_str) / 7);
}
get_days_between(start_date_str, end_date_str) {
let milliseconds_per_day = 24 * 60 * 60 * 1000;
return (this.treat_as_utc(end_date_str) - this.treat_as_utc(start_date_str)) / milliseconds_per_day;
}
// mutates
add_days(date, number_of_days) {
date.setDate(date.getDate() + number_of_days);
}
get_month_name() {}
}

View File

@ -13,13 +13,6 @@ export default class PercentageChart extends BaseChart {
this.max_slices = 10;
this.max_legend_points = 6;
this.colors = args.colors;
if(!this.colors || this.colors.length < this.data.labels.length) {
this.colors = ['light-blue', 'blue', 'violet', 'red', 'orange',
'yellow', 'green', 'light-green', 'purple', 'magenta'];
}
this.setup();
}
@ -86,8 +79,6 @@ export default class PercentageChart extends BaseChart {
this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
}
setup_utils() { }
make_graph_components() {
this.grand_total = this.slice_totals.reduce((a, b) => a + b, 0);
this.slices = [];

View File

@ -66,7 +66,6 @@ export default class PieChart extends BaseChart {
this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
}
setup_utils() { }
static getPositionByAngle(angle,radius){
return {
x:Math.sin(angle * ANGLE_RATIO) * radius,

View File

@ -0,0 +1,34 @@
// Playing around with dates
// https://stackoverflow.com/a/11252167/6495043
function treat_as_utc(date_str) {
let result = new Date(date_str);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
export function get_dd_mm_yyyy(date) {
let dd = date.getDate();
let mm = date.getMonth() + 1; // getMonth() is zero-based
return [
(dd>9 ? '' : '0') + dd,
(mm>9 ? '' : '0') + mm,
date.getFullYear()
].join('-');
}
export function get_weeks_between(start_date_str, end_date_str) {
return Math.ceil(get_days_between(start_date_str, end_date_str) / 7);
}
export function get_days_between(start_date_str, end_date_str) {
let milliseconds_per_day = 24 * 60 * 60 * 1000;
return (treat_as_utc(end_date_str) - treat_as_utc(start_date_str)) / milliseconds_per_day;
}
// mutates
export function add_days(date, number_of_days) {
date.setDate(date.getDate() + number_of_days);
}
// export function get_month_name() {}

View File

@ -83,18 +83,64 @@ export var UnitRenderer = (function() {
export function make_x_line(height, text_start_at, point, label_class, axis_line_class, x_pos) {
let line = $.createSVG('line', {
x1: 0,
x2: 0,
y1: 0,
y2: height
});
let text = $.createSVG('text', {
className: label_class,
x: 0,
y: text_start_at,
dy: '.71em',
innerHTML: point
});
let x_line = $.createSVG('g', {
className: `tick ${axis_line_class}`,
transform: `translate(${ x_pos }, 0)`
});
x_line.appendChild(line);
x_line.appendChild(text);
return x_line;
}
export function make_y_line() {}
export function make_y_line(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos, darker=false, line_type="") {
let line = $.createSVG('line', {
className: line_type === "dashed" ? "dashed": "",
x1: start_at,
x2: width,
y1: 0,
y2: 0
});
export function draw_x_line() {}
let text = $.createSVG('text', {
className: label_class,
x: text_end_at,
y: 0,
dy: '.32em',
innerHTML: point+""
});
export function draw_y_line() {}
let y_line = $.createSVG('g', {
className: `tick ${axis_line_class}`,
transform: `translate(0, ${y_pos})`,
'stroke-opacity': 1
});
export function label_x_line() {}
if(darker) {
line.style.stroke = "rgba(27, 31, 35, 0.6)";
}
export function label_y_line() {}
y_line.appendChild(line);
y_line.appendChild(text);
return y_line;
}
export function get_anim_x_line() {}

View File

@ -28,6 +28,117 @@ export function clump_intervals(start, interval_size, count) {
return intervals;
}
export function calc_intervals() {
//
// export function calc_intervals() {
// //
// }
export function calc_y_intervals(array) {
//*** Where the magic happens ***
// Calculates best-fit y intervals from given values
// and returns the interval array
// TODO: Fractions
let max_bound, min_bound, pos_no_of_parts, neg_no_of_parts, part_size; // eslint-disable-line no-unused-vars
// Critical values
let max_val = parseInt(Math.max(...array));
let min_val = parseInt(Math.min(...array));
if(min_val >= 0) {
min_val = 0;
}
let get_params = (value1, value2) => {
let bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size;
if((value1+"").length <= 1) {
[bound1, no_of_parts_1] = [10, 5];
} else {
[bound1, no_of_parts_1] = calc_upper_bound_and_no_of_parts(value1);
}
interval_size = bound1 / no_of_parts_1;
no_of_parts_2 = calc_no_of_parts(value2, interval_size);
bound2 = no_of_parts_2 * interval_size;
return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
};
const abs_min_val = min_val * -1;
if(abs_min_val <= max_val) {
// Get the positive region intervals
// then calc negative ones accordingly
[max_bound, min_bound, pos_no_of_parts, neg_no_of_parts, part_size]
= get_params(max_val, abs_min_val);
if(abs_min_val === 0) {
min_bound = 0; neg_no_of_parts = 0;
}
} else {
// Get the negative region here first
[min_bound, max_bound, neg_no_of_parts, pos_no_of_parts, part_size]
= get_params(abs_min_val, max_val);
}
// Make both region parts even
if(pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
if(neg_no_of_parts % 2 !== 0) {
// every increase in no_of_parts entails an increase in corresponding bound
// except here, it happens implicitly after every calc_no_of_parts() call
neg_no_of_parts++;
min_bound += part_size;
}
let no_of_parts = pos_no_of_parts + neg_no_of_parts;
if(no_of_parts > 5) {
no_of_parts /= 2;
part_size *= 2;
pos_no_of_parts /=2;
}
if (max_val < (pos_no_of_parts - 1) * part_size) {
no_of_parts--;
}
return get_intervals(
(-1) * min_bound,
part_size,
no_of_parts
);
}
function get_intervals(start, interval_size, count) {
let intervals = [];
for(var i = 0; i <= count; i++){
intervals.push(start);
start += interval_size;
}
return intervals;
}
function calc_upper_bound_and_no_of_parts(max_val) {
// Given a positive value, calculates a nice-number upper bound
// and a consequent optimal number of parts
const part_size = Math.pow(10, ((max_val+"").length - 1));
const no_of_parts = calc_no_of_parts(max_val, part_size);
// Use it to get a nice even upper bound
const upper_bound = part_size * no_of_parts;
return [upper_bound, no_of_parts];
}
function calc_no_of_parts(value, divisor) {
// value should be a positive number, divisor should be greater than 0
// returns an even no of parts
let no_of_parts = Math.ceil(value / divisor);
if(no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
return no_of_parts;
}
function get_optimal_no_of_parts(no_of_parts) {
// aka Divide by 2 if too large
return (no_of_parts < 5) ? no_of_parts : no_of_parts / 2;
}