add a couple of more utils
This commit is contained in:
parent
4a570faab6
commit
78727b0e7a
338
dist/frappe-charts.esm.js
vendored
338
dist/frappe-charts.esm.js
vendored
@ -1,20 +1,20 @@
|
|||||||
function $(expr, con) {
|
function $$1(expr, con) {
|
||||||
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
|
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$.create = (tag, o) => {
|
$$1.create = (tag, o) => {
|
||||||
var element = document.createElement(tag);
|
var element = document.createElement(tag);
|
||||||
|
|
||||||
for (var i in o) {
|
for (var i in o) {
|
||||||
var val = o[i];
|
var val = o[i];
|
||||||
|
|
||||||
if (i === "inside") {
|
if (i === "inside") {
|
||||||
$(val).appendChild(element);
|
$$1(val).appendChild(element);
|
||||||
}
|
}
|
||||||
else if (i === "around") {
|
else if (i === "around") {
|
||||||
var ref = $(val);
|
var ref = $$1(val);
|
||||||
ref.parentNode.insertBefore(element, ref);
|
ref.parentNode.insertBefore(element, ref);
|
||||||
element.appendChild(ref);
|
element.appendChild(ref);
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ function getElementContentWidth(element) {
|
|||||||
return element.clientWidth - padding;
|
return element.clientWidth - padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.bind = (element, o) => {
|
$$1.bind = (element, o) => {
|
||||||
if (element) {
|
if (element) {
|
||||||
for (var event in o) {
|
for (var event in o) {
|
||||||
var callback = o[event];
|
var callback = o[event];
|
||||||
@ -78,7 +78,7 @@ $.bind = (element, o) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.unbind = (element, o) => {
|
$$1.unbind = (element, o) => {
|
||||||
if (element) {
|
if (element) {
|
||||||
for (var event in o) {
|
for (var event in o) {
|
||||||
var callback = o[event];
|
var callback = o[event];
|
||||||
@ -90,7 +90,7 @@ $.unbind = (element, o) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.fire = (target, type, properties) => {
|
$$1.fire = (target, type, properties) => {
|
||||||
var evt = document.createEvent("HTMLEvents");
|
var evt = document.createEvent("HTMLEvents");
|
||||||
|
|
||||||
evt.initEvent(type, true, true );
|
evt.initEvent(type, true, true );
|
||||||
@ -102,6 +102,59 @@ $.fire = (target, type, properties) => {
|
|||||||
return target.dispatchEvent(evt);
|
return target.dispatchEvent(evt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of a number upto 2 decimal places.
|
||||||
|
* @param {Number} d Any number
|
||||||
|
*/
|
||||||
|
function floatTwo(d) {
|
||||||
|
return parseFloat(d.toFixed(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not two given arrays are equal.
|
||||||
|
* @param {Array} arr1 First array
|
||||||
|
* @param {Array} arr2 Second array
|
||||||
|
*/
|
||||||
|
function arraysEqual(arr1, arr2) {
|
||||||
|
if(arr1.length !== arr2.length) return false;
|
||||||
|
let areEqual = true;
|
||||||
|
arr1.map((d, i) => {
|
||||||
|
if(arr2[i] !== d) areEqual = false;
|
||||||
|
});
|
||||||
|
return areEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shuffles array in place. ES6 version
|
||||||
|
* @param {Array} array An array containing the items.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill an array with extra points
|
||||||
|
* @param {Array} array Array
|
||||||
|
* @param {Number} count number of filler elements
|
||||||
|
* @param {Object} element element to fill with
|
||||||
|
* @param {Boolean} start fill at start?
|
||||||
|
*/
|
||||||
|
function fillArray(array, count, element, start=false) {
|
||||||
|
if(!element) {
|
||||||
|
element = start ? array[0] : array[array.length - 1];
|
||||||
|
}
|
||||||
|
let fillerArray = new Array(Math.abs(count)).fill(element);
|
||||||
|
array = start ? fillerArray.concat(array) : array.concat(fillerArray);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns pixel width of string.
|
||||||
|
* @param {String} string
|
||||||
|
* @param {Number} charWidth Width of single char in pixels
|
||||||
|
*/
|
||||||
|
function getStringWidth(string, charWidth) {
|
||||||
|
return (string+"").length * charWidth;
|
||||||
|
}
|
||||||
|
|
||||||
function getBarHeightAndYAttr(yTop, zeroLine, totalHeight) {
|
function getBarHeightAndYAttr(yTop, zeroLine, totalHeight) {
|
||||||
let height, y;
|
let height, y;
|
||||||
if (yTop <= zeroLine) {
|
if (yTop <= zeroLine) {
|
||||||
@ -126,9 +179,25 @@ function getBarHeightAndYAttr(yTop, zeroLine, totalHeight) {
|
|||||||
return [height, y];
|
return [height, y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function equilizeNoOfPositions(old_x, old_y, new_x, new_y) {
|
||||||
|
let extra_count = new_x.length - old_x.length;
|
||||||
|
if(extra_count >= 0) {
|
||||||
|
// Substitute current unit set with a squiggled one (more units at end)
|
||||||
|
// in order to animate to stretch it later to new points
|
||||||
|
old_x = fillArray(old_x, extra_count);
|
||||||
|
old_y = fillArray(old_y, extra_count);
|
||||||
|
} else {
|
||||||
|
// Modify the new points to have extra points
|
||||||
|
// with the same position at end, old positions will squeeze in
|
||||||
|
new_x = fillArray(new_x, extra_count);
|
||||||
|
new_y = fillArray(new_y, extra_count);
|
||||||
|
}
|
||||||
|
return [old_x, old_y, new_x, new_y];
|
||||||
|
}
|
||||||
|
|
||||||
// Constants used
|
// Constants used
|
||||||
|
|
||||||
function $$1(expr, con) {
|
function $$2(expr, con) {
|
||||||
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
|
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +208,10 @@ function createSVG(tag, o) {
|
|||||||
var val = o[i];
|
var val = o[i];
|
||||||
|
|
||||||
if (i === "inside") {
|
if (i === "inside") {
|
||||||
$$1(val).appendChild(element);
|
$$2(val).appendChild(element);
|
||||||
}
|
}
|
||||||
else if (i === "around") {
|
else if (i === "around") {
|
||||||
var ref = $$1(val);
|
var ref = $$2(val);
|
||||||
ref.parentNode.insertBefore(element, ref);
|
ref.parentNode.insertBefore(element, ref);
|
||||||
element.appendChild(ref);
|
element.appendChild(ref);
|
||||||
|
|
||||||
@ -694,43 +763,6 @@ function getMaxCheckpoint(value, distribution) {
|
|||||||
return distribution.filter(d => d < value).length;
|
return distribution.filter(d => d < value).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value of a number upto 2 decimal places.
|
|
||||||
* @param {Number} d Any number
|
|
||||||
*/
|
|
||||||
function floatTwo(d) {
|
|
||||||
return parseFloat(d.toFixed(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not two given arrays are equal.
|
|
||||||
* @param {Array} arr1 First array
|
|
||||||
* @param {Array} arr2 Second array
|
|
||||||
*/
|
|
||||||
function arraysEqual(arr1, arr2) {
|
|
||||||
if(arr1.length !== arr2.length) return false;
|
|
||||||
let areEqual = true;
|
|
||||||
arr1.map((d, i) => {
|
|
||||||
if(arr2[i] !== d) areEqual = false;
|
|
||||||
});
|
|
||||||
return areEqual;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shuffles array in place. ES6 version
|
|
||||||
* @param {Array} array An array containing the items.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns pixel width of string.
|
|
||||||
* @param {String} string
|
|
||||||
* @param {Number} charWidth Width of single char in pixels
|
|
||||||
*/
|
|
||||||
function getStringWidth(string, charWidth) {
|
|
||||||
return (string+"").length * charWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SvgTip {
|
class SvgTip {
|
||||||
constructor({
|
constructor({
|
||||||
parent = null,
|
parent = null,
|
||||||
@ -763,7 +795,7 @@ class SvgTip {
|
|||||||
}
|
}
|
||||||
|
|
||||||
make_tooltip() {
|
make_tooltip() {
|
||||||
this.container = $.create('div', {
|
this.container = $$1.create('div', {
|
||||||
inside: this.parent,
|
inside: this.parent,
|
||||||
className: 'graph-svg-tip comparison',
|
className: 'graph-svg-tip comparison',
|
||||||
innerHTML: `<span class="title"></span>
|
innerHTML: `<span class="title"></span>
|
||||||
@ -793,7 +825,7 @@ class SvgTip {
|
|||||||
this.list_values.map((set, i) => {
|
this.list_values.map((set, i) => {
|
||||||
const color = this.colors[i] || 'black';
|
const color = this.colors[i] || 'black';
|
||||||
|
|
||||||
let li = $.create('li', {
|
let li = $$1.create('li', {
|
||||||
styles: {
|
styles: {
|
||||||
'border-top': `3px solid ${color}`
|
'border-top': `3px solid ${color}`
|
||||||
},
|
},
|
||||||
@ -911,7 +943,7 @@ const COMPATIBLE_CHARTS = {
|
|||||||
heatmap: []
|
heatmap: []
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Needs structure as per only labels/datasets
|
// Needs structure as per only labels/datasets
|
||||||
const COLOR_COMPATIBLE_CHARTS = {
|
const COLOR_COMPATIBLE_CHARTS = {
|
||||||
bar: ['line', 'scatter'],
|
bar: ['line', 'scatter'],
|
||||||
line: ['scatter', 'bar'],
|
line: ['scatter', 'bar'],
|
||||||
@ -945,6 +977,7 @@ class BaseChart {
|
|||||||
this.subtitle = subtitle;
|
this.subtitle = subtitle;
|
||||||
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.oldData = Object.assign({}, data);
|
||||||
|
|
||||||
this.specific_values = data.specific_values || [];
|
this.specific_values = data.specific_values || [];
|
||||||
this.summary = summary;
|
this.summary = summary;
|
||||||
@ -989,7 +1022,7 @@ class BaseChart {
|
|||||||
setColors(colors, type) {
|
setColors(colors, type) {
|
||||||
this.colors = colors;
|
this.colors = colors;
|
||||||
|
|
||||||
// TODO: Needs structure as per only labels/datasets
|
// Needs structure as per only labels/datasets
|
||||||
const list = type === 'percentage' || type === 'pie'
|
const list = type === 'percentage' || type === 'pie'
|
||||||
? this.data.labels
|
? this.data.labels
|
||||||
: this.data.datasets;
|
: this.data.datasets;
|
||||||
@ -1068,7 +1101,7 @@ class BaseChart {
|
|||||||
setup_base_values() {}
|
setup_base_values() {}
|
||||||
|
|
||||||
setup_container() {
|
setup_container() {
|
||||||
this.container = $.create('div', {
|
this.container = $$1.create('div', {
|
||||||
className: 'chart-container',
|
className: 'chart-container',
|
||||||
innerHTML: `<h6 class="title">${this.title}</h6>
|
innerHTML: `<h6 class="title">${this.title}</h6>
|
||||||
<h6 class="sub-title uppercase">${this.subtitle}</h6>
|
<h6 class="sub-title uppercase">${this.subtitle}</h6>
|
||||||
@ -1106,7 +1139,9 @@ class BaseChart {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_components() { }
|
setup_components() {}
|
||||||
|
setup_values() {}
|
||||||
|
setup_utils() {}
|
||||||
|
|
||||||
make_tooltip() {
|
make_tooltip() {
|
||||||
this.tip = new SvgTip({
|
this.tip = new SvgTip({
|
||||||
@ -1116,11 +1151,10 @@ class BaseChart {
|
|||||||
this.bind_tooltip();
|
this.bind_tooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
show_summary() {}
|
show_summary() {}
|
||||||
show_custom_summary() {
|
show_custom_summary() {
|
||||||
this.summary.map(d => {
|
this.summary.map(d => {
|
||||||
let stats = $.create('div', {
|
let stats = $$1.create('div', {
|
||||||
className: 'stats',
|
className: 'stats',
|
||||||
innerHTML: `<span class="indicator">
|
innerHTML: `<span class="indicator">
|
||||||
<i style="background:${d.color}"></i>
|
<i style="background:${d.color}"></i>
|
||||||
@ -1167,31 +1201,10 @@ class BaseChart {
|
|||||||
on_down_arrow() {}
|
on_down_arrow() {}
|
||||||
on_enter_key() {}
|
on_enter_key() {}
|
||||||
|
|
||||||
get_data_point(index=this.current_index) {
|
updateData() {}
|
||||||
// check for length
|
|
||||||
let data_point = {
|
|
||||||
index: index
|
|
||||||
};
|
|
||||||
let y = this.y[0];
|
|
||||||
['svg_units', 'y_tops', 'values'].map(key => {
|
|
||||||
let data_key = key.slice(0, key.length-1);
|
|
||||||
data_point[data_key] = y[key][index];
|
|
||||||
});
|
|
||||||
data_point.label = this.x[index];
|
|
||||||
return data_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_current_data_point(index) {
|
getDataPoint() {}
|
||||||
index = parseInt(index);
|
updateCurrentDataPoint() {}
|
||||||
if(index < 0) index = 0;
|
|
||||||
if(index >= this.x.length) index = this.x.length - 1;
|
|
||||||
if(index === this.current_index) return;
|
|
||||||
this.current_index = index;
|
|
||||||
$.fire(this.parent, "data-select", this.get_data_point());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Objects
|
|
||||||
setup_utils() { }
|
|
||||||
|
|
||||||
makeDrawAreaComponent(className, transform='') {
|
makeDrawAreaComponent(className, transform='') {
|
||||||
return makeSVGGroup(this.draw_area, className, transform);
|
return makeSVGGroup(this.draw_area, className, transform);
|
||||||
@ -1211,11 +1224,12 @@ class AxisChart extends BaseChart {
|
|||||||
this.format_tooltip_x = args.format_tooltip_x;
|
this.format_tooltip_x = args.format_tooltip_x;
|
||||||
|
|
||||||
this.zero_line = this.height;
|
this.zero_line = this.height;
|
||||||
|
|
||||||
// this.old_values = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_and_prepare_data() {
|
validate_and_prepare_data() {
|
||||||
|
this.y.forEach(function(d, i) {
|
||||||
|
d.index = i;
|
||||||
|
}, this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1426,8 +1440,8 @@ class AxisChart extends BaseChart {
|
|||||||
if(this.raw_chart_args.hasOwnProperty("init") && !this.raw_chart_args.init) {
|
if(this.raw_chart_args.hasOwnProperty("init") && !this.raw_chart_args.init) {
|
||||||
this.y.map((d, i) => {
|
this.y.map((d, i) => {
|
||||||
d.svg_units = [];
|
d.svg_units = [];
|
||||||
this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, this.colors[i]);
|
this.make_path && this.make_path(d, this.x_axis_positions, d.y_tops, this.colors[i]);
|
||||||
this.make_new_units(d, i);
|
this.make_new_units(d);
|
||||||
this.calc_y_dependencies();
|
this.calc_y_dependencies();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -1438,8 +1452,8 @@ class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
this.y.map((d, i) => {
|
this.y.map((d, i) => {
|
||||||
d.svg_units = [];
|
d.svg_units = [];
|
||||||
this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, this.colors[i]);
|
this.make_path && this.make_path(d, this.x_axis_positions, d.y_tops, this.colors[i]);
|
||||||
this.make_new_units(d, i);
|
this.make_new_units(d);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1451,8 +1465,8 @@ class AxisChart extends BaseChart {
|
|||||||
data.push({values: d.values});
|
data.push({values: d.values});
|
||||||
d.svg_units = [];
|
d.svg_units = [];
|
||||||
|
|
||||||
this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, this.colors[i]);
|
this.make_path && this.make_path(d, this.x_axis_positions, d.y_tops, this.colors[i]);
|
||||||
this.make_new_units(d, i);
|
this.make_new_units(d);
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -1471,12 +1485,12 @@ class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
make_new_units(d, i) {
|
make_new_units(d) {
|
||||||
this.make_new_units_for_dataset(
|
this.make_new_units_for_dataset(
|
||||||
this.x_axis_positions,
|
this.x_axis_positions,
|
||||||
d.y_tops,
|
d.y_tops,
|
||||||
this.colors[i],
|
this.colors[d.index],
|
||||||
i,
|
d.index,
|
||||||
this.y.length
|
this.y.length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1606,7 +1620,7 @@ class AxisChart extends BaseChart {
|
|||||||
this.sum_units
|
this.sum_units
|
||||||
);
|
);
|
||||||
|
|
||||||
// this.make_path && this.make_path(d, i, old_x, old_y, this.colors[i]);
|
// this.make_path && this.make_path(d, old_x, old_y, this.colors[i]);
|
||||||
|
|
||||||
this.updating = false;
|
this.updating = false;
|
||||||
}
|
}
|
||||||
@ -1621,13 +1635,13 @@ class AxisChart extends BaseChart {
|
|||||||
|
|
||||||
show_averages() {
|
show_averages() {
|
||||||
this.old_specific_values = this.specific_values.slice();
|
this.old_specific_values = this.specific_values.slice();
|
||||||
this.y.map((d, i) => {
|
this.y.map(d => {
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
d.values.map(e => {sum+=e;});
|
d.values.map(e => {sum+=e;});
|
||||||
let average = sum/d.values.length;
|
let average = sum/d.values.length;
|
||||||
|
|
||||||
this.specific_values.push({
|
this.specific_values.push({
|
||||||
title: "AVG" + " " + (i+1),
|
title: "AVG" + " " + (d.index+1),
|
||||||
line_type: "dashed",
|
line_type: "dashed",
|
||||||
value: average,
|
value: average,
|
||||||
auto: 1
|
auto: 1
|
||||||
@ -1664,10 +1678,8 @@ class AxisChart extends BaseChart {
|
|||||||
|
|
||||||
this.old_y_values = this.y.map(d => d.values);
|
this.old_y_values = this.y.map(d => d.values);
|
||||||
|
|
||||||
this.no_of_extra_pts = new_x.length - this.x.length;
|
|
||||||
|
|
||||||
// Just update values prop, setup_x/y() will do the rest
|
// Just update values prop, setup_x/y() will do the rest
|
||||||
if(new_y) this.y.map((d, i) => {d.values = new_y[i].values;});
|
if(new_y) this.y.map(d => {d.values = new_y[d.index].values;});
|
||||||
if(new_x) this.x = new_x;
|
if(new_x) this.x = new_x;
|
||||||
|
|
||||||
this.setup_x();
|
this.setup_x();
|
||||||
@ -1747,34 +1759,38 @@ class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
animate_graphs() {
|
animate_graphs() {
|
||||||
this.y.map((d, i) => {
|
this.y.map(d => {
|
||||||
// Pre-prep, equilize no of positions between old and new
|
// Pre-prep, equilize no of positions between old and new
|
||||||
let [old_x, old_y, new_x, new_y] = this.calc_old_and_new_postions(d, i);
|
let [old_x, old_y, new_x, new_y] = equilizeNoOfPositions(
|
||||||
if(this.no_of_extra_pts >= 0) {
|
this.x_old_axis_positions.slice(),
|
||||||
this.make_path && this.make_path(d, i, old_x, old_y, this.colors[i]);
|
this.old_y_axis_tops[d.index].slice(),
|
||||||
this.make_new_units_for_dataset(old_x, old_y, this.colors[i], i, this.y.length);
|
this.x_axis_positions.slice(),
|
||||||
|
d.y_tops.slice()
|
||||||
|
);
|
||||||
|
if(new_x.length - old_x.length > 0) {
|
||||||
|
this.make_path && this.make_path(d, old_x, old_y, this.colors[d.index]);
|
||||||
|
this.make_new_units_for_dataset(old_x, old_y, this.colors[d.index], d.index, this.y.length);
|
||||||
}
|
}
|
||||||
d.path && this.animate_path(d, i, old_x, old_y, new_x, new_y);
|
d.path && this.animate_path(d, new_x, new_y);
|
||||||
this.animate_units(d, i, old_x, old_y, new_x, new_y);
|
this.animate_units(d, old_x, old_y, new_x, new_y);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: replace with real units
|
// TODO: replace with real units
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.y.map((d, i) => {
|
this.y.map(d => {
|
||||||
this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, this.colors[i]);
|
this.make_path && this.make_path(d, this.x_axis_positions, d.y_tops, this.colors[d.index]);
|
||||||
this.make_new_units(d, i);
|
this.make_new_units(d);
|
||||||
});
|
});
|
||||||
}, 400);
|
}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
animate_path(d, i, old_x, old_y, new_x, new_y) {
|
animate_path(d, new_x, new_y) {
|
||||||
const newPointsList = new_y.map((y, i) => (new_x[i] + ',' + y));
|
const newPointsList = new_y.map((y, i) => (new_x[i] + ',' + y));
|
||||||
const newPathStr = newPointsList.join("L");
|
|
||||||
this.elements_to_animate = this.elements_to_animate
|
this.elements_to_animate = this.elements_to_animate
|
||||||
.concat(this.animator['path'](d, newPathStr));
|
.concat(this.animator['path'](d, newPointsList.join("L")));
|
||||||
}
|
}
|
||||||
|
|
||||||
animate_units(d, index, old_x, old_y, new_x, new_y) {
|
animate_units(d, old_x, old_y, new_x, new_y) {
|
||||||
let type = this.unit_args.type;
|
let type = this.unit_args.type;
|
||||||
|
|
||||||
d.svg_units.map((unit, i) => {
|
d.svg_units.map((unit, i) => {
|
||||||
@ -1783,51 +1799,12 @@ class AxisChart extends BaseChart {
|
|||||||
{unit:unit, array:d.svg_units, index: i}, // unit, with info to replace where it came from in the data
|
{unit:unit, array:d.svg_units, index: i}, // unit, with info to replace where it came from in the data
|
||||||
new_x[i],
|
new_x[i],
|
||||||
new_y[i],
|
new_y[i],
|
||||||
index,
|
d.index,
|
||||||
this.y.length
|
this.y.length
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
calc_old_and_new_postions(d, i) {
|
|
||||||
let old_x = this.x_old_axis_positions.slice();
|
|
||||||
let new_x = this.x_axis_positions.slice();
|
|
||||||
|
|
||||||
let old_y = this.old_y_axis_tops[i].slice();
|
|
||||||
let new_y = d.y_tops.slice();
|
|
||||||
|
|
||||||
const last_old_x_pos = old_x[old_x.length - 1];
|
|
||||||
const last_old_y_pos = old_y[old_y.length - 1];
|
|
||||||
|
|
||||||
const last_new_x_pos = new_x[new_x.length - 1];
|
|
||||||
const last_new_y_pos = new_y[new_y.length - 1];
|
|
||||||
|
|
||||||
if(this.no_of_extra_pts >= 0) {
|
|
||||||
// First substitute current path with a squiggled one
|
|
||||||
// (that looks the same but has more points at end),
|
|
||||||
// then animate to stretch it later to new points
|
|
||||||
// (new points already have more points)
|
|
||||||
|
|
||||||
// Hence, the extra end points will correspond to current(old) positions
|
|
||||||
let filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_x_pos);
|
|
||||||
let filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_y_pos);
|
|
||||||
|
|
||||||
old_x = old_x.concat(filler_x);
|
|
||||||
old_y = old_y.concat(filler_y);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Just modify the new points to have extra points
|
|
||||||
// with the same position at end
|
|
||||||
let filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_x_pos);
|
|
||||||
let filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_y_pos);
|
|
||||||
|
|
||||||
new_x = new_x.concat(filler_x);
|
|
||||||
new_y = new_y.concat(filler_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [old_x, old_y, new_x, new_y];
|
|
||||||
}
|
|
||||||
|
|
||||||
make_anim_x_axis(height, text_start_at, axis_line_class) {
|
make_anim_x_axis(height, text_start_at, axis_line_class) {
|
||||||
// Animate X AXIS to account for more or less axis lines
|
// Animate X AXIS to account for more or less axis lines
|
||||||
|
|
||||||
@ -1993,6 +1970,29 @@ class AxisChart extends BaseChart {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDataPoint(index=this.current_index) {
|
||||||
|
// check for length
|
||||||
|
let data_point = {
|
||||||
|
index: index
|
||||||
|
};
|
||||||
|
let y = this.y[0];
|
||||||
|
['svg_units', 'y_tops', 'values'].map(key => {
|
||||||
|
let data_key = key.slice(0, key.length-1);
|
||||||
|
data_point[data_key] = y[key][index];
|
||||||
|
});
|
||||||
|
data_point.label = this.x[index];
|
||||||
|
return data_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCurrentDataPoint(index) {
|
||||||
|
index = parseInt(index);
|
||||||
|
if(index < 0) index = 0;
|
||||||
|
if(index >= this.x.length) index = this.x.length - 1;
|
||||||
|
if(index === this.current_index) return;
|
||||||
|
this.current_index = index;
|
||||||
|
$.fire(this.parent, "data-select", this.getDataPoint());
|
||||||
|
}
|
||||||
|
|
||||||
set_avg_unit_width_and_x_offset() {
|
set_avg_unit_width_and_x_offset() {
|
||||||
// Set the ... you get it
|
// Set the ... you get it
|
||||||
this.avg_unit_width = this.width/(this.x.length - 1);
|
this.avg_unit_width = this.width/(this.x.length - 1);
|
||||||
@ -2012,7 +2012,7 @@ class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
calc_y_dependencies() {
|
calc_y_dependencies() {
|
||||||
this.y_min_tops = new Array(this.x_axis_positions.length).fill(9999);
|
this.y_min_tops = new Array(this.x.length).fill(9999);
|
||||||
this.y.map(d => {
|
this.y.map(d => {
|
||||||
d.y_tops = d.values.map( val => floatTwo(this.zero_line - val * this.multiplier));
|
d.y_tops = d.values.map( val => floatTwo(this.zero_line - val * this.multiplier));
|
||||||
d.y_tops.map( (y_top, i) => {
|
d.y_tops.map( (y_top, i) => {
|
||||||
@ -2051,7 +2051,7 @@ class BarChart extends AxisChart {
|
|||||||
// Just make one out of the first element
|
// Just make one out of the first element
|
||||||
let index = this.x.length - 1;
|
let index = this.x.length - 1;
|
||||||
let unit = this.y[0].svg_units[index];
|
let unit = this.y[0].svg_units[index];
|
||||||
this.update_current_data_point(index);
|
this.updateCurrentDataPoint(index);
|
||||||
|
|
||||||
if(this.overlay) {
|
if(this.overlay) {
|
||||||
this.overlay.parentNode.removeChild(this.overlay);
|
this.overlay.parentNode.removeChild(this.overlay);
|
||||||
@ -2073,7 +2073,7 @@ class BarChart extends AxisChart {
|
|||||||
units_array.map(unit => {
|
units_array.map(unit => {
|
||||||
unit.addEventListener('click', () => {
|
unit.addEventListener('click', () => {
|
||||||
let index = unit.getAttribute('data-point-index');
|
let index = unit.getAttribute('data-point-index');
|
||||||
this.update_current_data_point(index);
|
this.updateCurrentDataPoint(index);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -2093,11 +2093,11 @@ class BarChart extends AxisChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
on_left_arrow() {
|
on_left_arrow() {
|
||||||
this.update_current_data_point(this.current_index - 1);
|
this.updateCurrentDataPoint(this.current_index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
on_right_arrow() {
|
on_right_arrow() {
|
||||||
this.update_current_data_point(this.current_index + 1);
|
this.updateCurrentDataPoint(this.current_index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_avg_unit_width_and_x_offset() {
|
set_avg_unit_width_and_x_offset() {
|
||||||
@ -2162,19 +2162,19 @@ class LineChart extends AxisChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
make_paths() {
|
make_paths() {
|
||||||
this.y.map((d, i) => {
|
this.y.map(d => {
|
||||||
this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
|
this.make_path(d, this.x_axis_positions, d.y_tops, d.color || this.colors[d.index]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
make_path(d, i, x_positions, y_positions, color) {
|
make_path(d, x_positions, y_positions, color) {
|
||||||
let points_list = y_positions.map((y, i) => (x_positions[i] + ',' + y));
|
let points_list = y_positions.map((y, i) => (x_positions[i] + ',' + y));
|
||||||
let points_str = points_list.join("L");
|
let points_str = points_list.join("L");
|
||||||
|
|
||||||
this.paths_groups[i].textContent = '';
|
this.paths_groups[d.index].textContent = '';
|
||||||
|
|
||||||
d.path = makePath("M"+points_str, 'line-graph-path', color);
|
d.path = makePath("M"+points_str, 'line-graph-path', color);
|
||||||
this.paths_groups[i].appendChild(d.path);
|
this.paths_groups[d.index].appendChild(d.path);
|
||||||
|
|
||||||
if(this.heatline) {
|
if(this.heatline) {
|
||||||
let gradient_id = makeGradient(this.svg_defs, color);
|
let gradient_id = makeGradient(this.svg_defs, color);
|
||||||
@ -2182,16 +2182,16 @@ class LineChart extends AxisChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(this.region_fill) {
|
if(this.region_fill) {
|
||||||
this.fill_region_for_dataset(d, i, color, points_str);
|
this.fill_region_for_dataset(d, color, points_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_region_for_dataset(d, i, color, points_str) {
|
fill_region_for_dataset(d, color, points_str) {
|
||||||
let gradient_id = makeGradient(this.svg_defs, color, true);
|
let gradient_id = makeGradient(this.svg_defs, color, true);
|
||||||
let pathStr = "M" + `0,${this.zero_line}L` + points_str + `L${this.width},${this.zero_line}`;
|
let pathStr = "M" + `0,${this.zero_line}L` + points_str + `L${this.width},${this.zero_line}`;
|
||||||
|
|
||||||
d.regionPath = makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id})`);
|
d.regionPath = makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id})`);
|
||||||
this.paths_groups[i].appendChild(d.regionPath);
|
this.paths_groups[d.index].appendChild(d.regionPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2250,19 +2250,19 @@ class PercentageChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
make_draw_area() {
|
make_draw_area() {
|
||||||
this.chart_div = $.create('div', {
|
this.chart_div = $$1.create('div', {
|
||||||
className: 'div',
|
className: 'div',
|
||||||
inside: this.chart_wrapper
|
inside: this.chart_wrapper
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chart = $.create('div', {
|
this.chart = $$1.create('div', {
|
||||||
className: 'progress-chart',
|
className: 'progress-chart',
|
||||||
inside: this.chart_div
|
inside: this.chart_div
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_components() {
|
setup_components() {
|
||||||
this.percentage_bar = $.create('div', {
|
this.percentage_bar = $$1.create('div', {
|
||||||
className: 'progress',
|
className: 'progress',
|
||||||
inside: this.chart
|
inside: this.chart
|
||||||
});
|
});
|
||||||
@ -2307,7 +2307,7 @@ class PercentageChart extends BaseChart {
|
|||||||
this.grand_total = this.slice_totals.reduce((a, b) => a + b, 0);
|
this.grand_total = this.slice_totals.reduce((a, b) => a + b, 0);
|
||||||
this.slices = [];
|
this.slices = [];
|
||||||
this.slice_totals.map((total, i) => {
|
this.slice_totals.map((total, i) => {
|
||||||
let slice = $.create('div', {
|
let slice = $$1.create('div', {
|
||||||
className: `progress-bar`,
|
className: `progress-bar`,
|
||||||
inside: this.percentage_bar,
|
inside: this.percentage_bar,
|
||||||
styles: {
|
styles: {
|
||||||
@ -2341,7 +2341,7 @@ class PercentageChart extends BaseChart {
|
|||||||
? this.formatted_labels : this.labels;
|
? this.formatted_labels : this.labels;
|
||||||
this.legend_totals.map((d, i) => {
|
this.legend_totals.map((d, i) => {
|
||||||
if(d) {
|
if(d) {
|
||||||
let stats = $.create('div', {
|
let stats = $$1.create('div', {
|
||||||
className: 'stats',
|
className: 'stats',
|
||||||
inside: this.stats_wrapper
|
inside: this.stats_wrapper
|
||||||
});
|
});
|
||||||
@ -2550,7 +2550,7 @@ class PieChart extends BaseChart {
|
|||||||
const color = this.colors[i];
|
const color = this.colors[i];
|
||||||
|
|
||||||
if(d) {
|
if(d) {
|
||||||
let stats = $.create('div', {
|
let stats = $$1.create('div', {
|
||||||
className: 'stats',
|
className: 'stats',
|
||||||
inside: this.stats_wrapper
|
inside: this.stats_wrapper
|
||||||
});
|
});
|
||||||
|
|||||||
2
dist/frappe-charts.min.cjs.js
vendored
2
dist/frappe-charts.min.cjs.js
vendored
File diff suppressed because one or more lines are too long
2
dist/frappe-charts.min.esm.js
vendored
2
dist/frappe-charts.min.esm.js
vendored
File diff suppressed because one or more lines are too long
2
dist/frappe-charts.min.iife.js
vendored
2
dist/frappe-charts.min.iife.js
vendored
File diff suppressed because one or more lines are too long
2
docs/assets/js/frappe-charts.min.js
vendored
2
docs/assets/js/frappe-charts.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,5 +1,6 @@
|
|||||||
import { offset } from '../utils/dom';
|
import { offset } from '../utils/dom';
|
||||||
import { UnitRenderer, makeXLine, makeYLine } from '../utils/draw';
|
import { UnitRenderer, makeXLine, makeYLine } from '../utils/draw';
|
||||||
|
import { equilizeNoOfPositions } from '../utils/draw-utils';
|
||||||
import { Animator } from '../utils/animate';
|
import { Animator } from '../utils/animate';
|
||||||
import { runSVGAnimation } from '../utils/animation';
|
import { runSVGAnimation } from '../utils/animation';
|
||||||
import { calcIntervals } from '../utils/intervals';
|
import { calcIntervals } from '../utils/intervals';
|
||||||
@ -19,11 +20,12 @@ export default class AxisChart extends BaseChart {
|
|||||||
this.format_tooltip_x = args.format_tooltip_x;
|
this.format_tooltip_x = args.format_tooltip_x;
|
||||||
|
|
||||||
this.zero_line = this.height;
|
this.zero_line = this.height;
|
||||||
|
|
||||||
// this.old_values = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_and_prepare_data() {
|
validate_and_prepare_data() {
|
||||||
|
this.y.forEach(function(d, i) {
|
||||||
|
d.index = i;
|
||||||
|
}, this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +236,8 @@ export default class AxisChart extends BaseChart {
|
|||||||
if(this.raw_chart_args.hasOwnProperty("init") && !this.raw_chart_args.init) {
|
if(this.raw_chart_args.hasOwnProperty("init") && !this.raw_chart_args.init) {
|
||||||
this.y.map((d, i) => {
|
this.y.map((d, i) => {
|
||||||
d.svg_units = [];
|
d.svg_units = [];
|
||||||
this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, this.colors[i]);
|
this.make_path && this.make_path(d, this.x_axis_positions, d.y_tops, this.colors[i]);
|
||||||
this.make_new_units(d, i);
|
this.make_new_units(d);
|
||||||
this.calc_y_dependencies();
|
this.calc_y_dependencies();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -246,8 +248,8 @@ export default class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
this.y.map((d, i) => {
|
this.y.map((d, i) => {
|
||||||
d.svg_units = [];
|
d.svg_units = [];
|
||||||
this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, this.colors[i]);
|
this.make_path && this.make_path(d, this.x_axis_positions, d.y_tops, this.colors[i]);
|
||||||
this.make_new_units(d, i);
|
this.make_new_units(d);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,8 +261,8 @@ export default class AxisChart extends BaseChart {
|
|||||||
data.push({values: d.values});
|
data.push({values: d.values});
|
||||||
d.svg_units = [];
|
d.svg_units = [];
|
||||||
|
|
||||||
this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, this.colors[i]);
|
this.make_path && this.make_path(d, this.x_axis_positions, d.y_tops, this.colors[i]);
|
||||||
this.make_new_units(d, i);
|
this.make_new_units(d);
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -279,12 +281,12 @@ export default class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
make_new_units(d, i) {
|
make_new_units(d) {
|
||||||
this.make_new_units_for_dataset(
|
this.make_new_units_for_dataset(
|
||||||
this.x_axis_positions,
|
this.x_axis_positions,
|
||||||
d.y_tops,
|
d.y_tops,
|
||||||
this.colors[i],
|
this.colors[d.index],
|
||||||
i,
|
d.index,
|
||||||
this.y.length
|
this.y.length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -414,7 +416,7 @@ export default class AxisChart extends BaseChart {
|
|||||||
this.sum_units
|
this.sum_units
|
||||||
);
|
);
|
||||||
|
|
||||||
// this.make_path && this.make_path(d, i, old_x, old_y, this.colors[i]);
|
// this.make_path && this.make_path(d, old_x, old_y, this.colors[i]);
|
||||||
|
|
||||||
this.updating = false;
|
this.updating = false;
|
||||||
}
|
}
|
||||||
@ -429,13 +431,13 @@ export default class AxisChart extends BaseChart {
|
|||||||
|
|
||||||
show_averages() {
|
show_averages() {
|
||||||
this.old_specific_values = this.specific_values.slice();
|
this.old_specific_values = this.specific_values.slice();
|
||||||
this.y.map((d, i) => {
|
this.y.map(d => {
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
d.values.map(e => {sum+=e;});
|
d.values.map(e => {sum+=e;});
|
||||||
let average = sum/d.values.length;
|
let average = sum/d.values.length;
|
||||||
|
|
||||||
this.specific_values.push({
|
this.specific_values.push({
|
||||||
title: "AVG" + " " + (i+1),
|
title: "AVG" + " " + (d.index+1),
|
||||||
line_type: "dashed",
|
line_type: "dashed",
|
||||||
value: average,
|
value: average,
|
||||||
auto: 1
|
auto: 1
|
||||||
@ -472,10 +474,8 @@ export default class AxisChart extends BaseChart {
|
|||||||
|
|
||||||
this.old_y_values = this.y.map(d => d.values);
|
this.old_y_values = this.y.map(d => d.values);
|
||||||
|
|
||||||
this.no_of_extra_pts = new_x.length - this.x.length;
|
|
||||||
|
|
||||||
// Just update values prop, setup_x/y() will do the rest
|
// Just update values prop, setup_x/y() will do the rest
|
||||||
if(new_y) this.y.map((d, i) => {d.values = new_y[i].values;});
|
if(new_y) this.y.map(d => {d.values = new_y[d.index].values;});
|
||||||
if(new_x) this.x = new_x;
|
if(new_x) this.x = new_x;
|
||||||
|
|
||||||
this.setup_x();
|
this.setup_x();
|
||||||
@ -555,34 +555,38 @@ export default class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
animate_graphs() {
|
animate_graphs() {
|
||||||
this.y.map((d, i) => {
|
this.y.map(d => {
|
||||||
// Pre-prep, equilize no of positions between old and new
|
// Pre-prep, equilize no of positions between old and new
|
||||||
let [old_x, old_y, new_x, new_y] = this.calc_old_and_new_postions(d, i);
|
let [old_x, old_y, new_x, new_y] = equilizeNoOfPositions(
|
||||||
if(this.no_of_extra_pts >= 0) {
|
this.x_old_axis_positions.slice(),
|
||||||
this.make_path && this.make_path(d, i, old_x, old_y, this.colors[i]);
|
this.old_y_axis_tops[d.index].slice(),
|
||||||
this.make_new_units_for_dataset(old_x, old_y, this.colors[i], i, this.y.length);
|
this.x_axis_positions.slice(),
|
||||||
|
d.y_tops.slice()
|
||||||
|
);
|
||||||
|
if(new_x.length - old_x.length > 0) {
|
||||||
|
this.make_path && this.make_path(d, old_x, old_y, this.colors[d.index]);
|
||||||
|
this.make_new_units_for_dataset(old_x, old_y, this.colors[d.index], d.index, this.y.length);
|
||||||
}
|
}
|
||||||
d.path && this.animate_path(d, i, old_x, old_y, new_x, new_y);
|
d.path && this.animate_path(d, new_x, new_y);
|
||||||
this.animate_units(d, i, old_x, old_y, new_x, new_y);
|
this.animate_units(d, old_x, old_y, new_x, new_y);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: replace with real units
|
// TODO: replace with real units
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.y.map((d, i) => {
|
this.y.map(d => {
|
||||||
this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, this.colors[i]);
|
this.make_path && this.make_path(d, this.x_axis_positions, d.y_tops, this.colors[d.index]);
|
||||||
this.make_new_units(d, i);
|
this.make_new_units(d);
|
||||||
});
|
});
|
||||||
}, 400);
|
}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
animate_path(d, i, old_x, old_y, new_x, new_y) {
|
animate_path(d, new_x, new_y) {
|
||||||
const newPointsList = new_y.map((y, i) => (new_x[i] + ',' + y));
|
const newPointsList = new_y.map((y, i) => (new_x[i] + ',' + y));
|
||||||
const newPathStr = newPointsList.join("L");
|
|
||||||
this.elements_to_animate = this.elements_to_animate
|
this.elements_to_animate = this.elements_to_animate
|
||||||
.concat(this.animator['path'](d, newPathStr));
|
.concat(this.animator['path'](d, newPointsList.join("L")));
|
||||||
}
|
}
|
||||||
|
|
||||||
animate_units(d, index, old_x, old_y, new_x, new_y) {
|
animate_units(d, old_x, old_y, new_x, new_y) {
|
||||||
let type = this.unit_args.type;
|
let type = this.unit_args.type;
|
||||||
|
|
||||||
d.svg_units.map((unit, i) => {
|
d.svg_units.map((unit, i) => {
|
||||||
@ -591,51 +595,12 @@ export default class AxisChart extends BaseChart {
|
|||||||
{unit:unit, array:d.svg_units, index: i}, // unit, with info to replace where it came from in the data
|
{unit:unit, array:d.svg_units, index: i}, // unit, with info to replace where it came from in the data
|
||||||
new_x[i],
|
new_x[i],
|
||||||
new_y[i],
|
new_y[i],
|
||||||
index,
|
d.index,
|
||||||
this.y.length
|
this.y.length
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
calc_old_and_new_postions(d, i) {
|
|
||||||
let old_x = this.x_old_axis_positions.slice();
|
|
||||||
let new_x = this.x_axis_positions.slice();
|
|
||||||
|
|
||||||
let old_y = this.old_y_axis_tops[i].slice();
|
|
||||||
let new_y = d.y_tops.slice();
|
|
||||||
|
|
||||||
const last_old_x_pos = old_x[old_x.length - 1];
|
|
||||||
const last_old_y_pos = old_y[old_y.length - 1];
|
|
||||||
|
|
||||||
const last_new_x_pos = new_x[new_x.length - 1];
|
|
||||||
const last_new_y_pos = new_y[new_y.length - 1];
|
|
||||||
|
|
||||||
if(this.no_of_extra_pts >= 0) {
|
|
||||||
// First substitute current path with a squiggled one
|
|
||||||
// (that looks the same but has more points at end),
|
|
||||||
// then animate to stretch it later to new points
|
|
||||||
// (new points already have more points)
|
|
||||||
|
|
||||||
// Hence, the extra end points will correspond to current(old) positions
|
|
||||||
let filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_x_pos);
|
|
||||||
let filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_y_pos);
|
|
||||||
|
|
||||||
old_x = old_x.concat(filler_x);
|
|
||||||
old_y = old_y.concat(filler_y);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Just modify the new points to have extra points
|
|
||||||
// with the same position at end
|
|
||||||
let filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_x_pos);
|
|
||||||
let filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_y_pos);
|
|
||||||
|
|
||||||
new_x = new_x.concat(filler_x);
|
|
||||||
new_y = new_y.concat(filler_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [old_x, old_y, new_x, new_y];
|
|
||||||
}
|
|
||||||
|
|
||||||
make_anim_x_axis(height, text_start_at, axis_line_class) {
|
make_anim_x_axis(height, text_start_at, axis_line_class) {
|
||||||
// Animate X AXIS to account for more or less axis lines
|
// Animate X AXIS to account for more or less axis lines
|
||||||
|
|
||||||
@ -801,6 +766,29 @@ export default class AxisChart extends BaseChart {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDataPoint(index=this.current_index) {
|
||||||
|
// check for length
|
||||||
|
let data_point = {
|
||||||
|
index: index
|
||||||
|
};
|
||||||
|
let y = this.y[0];
|
||||||
|
['svg_units', 'y_tops', 'values'].map(key => {
|
||||||
|
let data_key = key.slice(0, key.length-1);
|
||||||
|
data_point[data_key] = y[key][index];
|
||||||
|
});
|
||||||
|
data_point.label = this.x[index];
|
||||||
|
return data_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCurrentDataPoint(index) {
|
||||||
|
index = parseInt(index);
|
||||||
|
if(index < 0) index = 0;
|
||||||
|
if(index >= this.x.length) index = this.x.length - 1;
|
||||||
|
if(index === this.current_index) return;
|
||||||
|
this.current_index = index;
|
||||||
|
$.fire(this.parent, "data-select", this.getDataPoint());
|
||||||
|
}
|
||||||
|
|
||||||
set_avg_unit_width_and_x_offset() {
|
set_avg_unit_width_and_x_offset() {
|
||||||
// Set the ... you get it
|
// Set the ... you get it
|
||||||
this.avg_unit_width = this.width/(this.x.length - 1);
|
this.avg_unit_width = this.width/(this.x.length - 1);
|
||||||
@ -820,7 +808,7 @@ export default class AxisChart extends BaseChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
calc_y_dependencies() {
|
calc_y_dependencies() {
|
||||||
this.y_min_tops = new Array(this.x_axis_positions.length).fill(9999);
|
this.y_min_tops = new Array(this.x.length).fill(9999);
|
||||||
this.y.map(d => {
|
this.y.map(d => {
|
||||||
d.y_tops = d.values.map( val => floatTwo(this.zero_line - val * this.multiplier));
|
d.y_tops = d.values.map( val => floatTwo(this.zero_line - val * this.multiplier));
|
||||||
d.y_tops.map( (y_top, i) => {
|
d.y_tops.map( (y_top, i) => {
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export default class BarChart extends AxisChart {
|
|||||||
// Just make one out of the first element
|
// Just make one out of the first element
|
||||||
let index = this.x.length - 1;
|
let index = this.x.length - 1;
|
||||||
let unit = this.y[0].svg_units[index];
|
let unit = this.y[0].svg_units[index];
|
||||||
this.update_current_data_point(index);
|
this.updateCurrentDataPoint(index);
|
||||||
|
|
||||||
if(this.overlay) {
|
if(this.overlay) {
|
||||||
this.overlay.parentNode.removeChild(this.overlay);
|
this.overlay.parentNode.removeChild(this.overlay);
|
||||||
@ -47,7 +47,7 @@ export default class BarChart extends AxisChart {
|
|||||||
units_array.map(unit => {
|
units_array.map(unit => {
|
||||||
unit.addEventListener('click', () => {
|
unit.addEventListener('click', () => {
|
||||||
let index = unit.getAttribute('data-point-index');
|
let index = unit.getAttribute('data-point-index');
|
||||||
this.update_current_data_point(index);
|
this.updateCurrentDataPoint(index);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -67,11 +67,11 @@ export default class BarChart extends AxisChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
on_left_arrow() {
|
on_left_arrow() {
|
||||||
this.update_current_data_point(this.current_index - 1);
|
this.updateCurrentDataPoint(this.current_index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
on_right_arrow() {
|
on_right_arrow() {
|
||||||
this.update_current_data_point(this.current_index + 1);
|
this.updateCurrentDataPoint(this.current_index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_avg_unit_width_and_x_offset() {
|
set_avg_unit_width_and_x_offset() {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ const COMPATIBLE_CHARTS = {
|
|||||||
heatmap: []
|
heatmap: []
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Needs structure as per only labels/datasets
|
// Needs structure as per only labels/datasets
|
||||||
const COLOR_COMPATIBLE_CHARTS = {
|
const COLOR_COMPATIBLE_CHARTS = {
|
||||||
bar: ['line', 'scatter'],
|
bar: ['line', 'scatter'],
|
||||||
line: ['scatter', 'bar'],
|
line: ['scatter', 'bar'],
|
||||||
@ -50,6 +50,7 @@ export default class BaseChart {
|
|||||||
this.subtitle = subtitle;
|
this.subtitle = subtitle;
|
||||||
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.oldData = Object.assign({}, data);
|
||||||
|
|
||||||
this.specific_values = data.specific_values || [];
|
this.specific_values = data.specific_values || [];
|
||||||
this.summary = summary;
|
this.summary = summary;
|
||||||
@ -94,7 +95,7 @@ export default class BaseChart {
|
|||||||
setColors(colors, type) {
|
setColors(colors, type) {
|
||||||
this.colors = colors;
|
this.colors = colors;
|
||||||
|
|
||||||
// TODO: Needs structure as per only labels/datasets
|
// Needs structure as per only labels/datasets
|
||||||
const list = type === 'percentage' || type === 'pie'
|
const list = type === 'percentage' || type === 'pie'
|
||||||
? this.data.labels
|
? this.data.labels
|
||||||
: this.data.datasets;
|
: this.data.datasets;
|
||||||
@ -211,7 +212,9 @@ export default class BaseChart {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_components() { }
|
setup_components() {}
|
||||||
|
setup_values() {}
|
||||||
|
setup_utils() {}
|
||||||
|
|
||||||
make_tooltip() {
|
make_tooltip() {
|
||||||
this.tip = new SvgTip({
|
this.tip = new SvgTip({
|
||||||
@ -221,7 +224,6 @@ export default class BaseChart {
|
|||||||
this.bind_tooltip();
|
this.bind_tooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
show_summary() {}
|
show_summary() {}
|
||||||
show_custom_summary() {
|
show_custom_summary() {
|
||||||
this.summary.map(d => {
|
this.summary.map(d => {
|
||||||
@ -272,31 +274,10 @@ export default class BaseChart {
|
|||||||
on_down_arrow() {}
|
on_down_arrow() {}
|
||||||
on_enter_key() {}
|
on_enter_key() {}
|
||||||
|
|
||||||
get_data_point(index=this.current_index) {
|
updateData() {}
|
||||||
// check for length
|
|
||||||
let data_point = {
|
|
||||||
index: index
|
|
||||||
};
|
|
||||||
let y = this.y[0];
|
|
||||||
['svg_units', 'y_tops', 'values'].map(key => {
|
|
||||||
let data_key = key.slice(0, key.length-1);
|
|
||||||
data_point[data_key] = y[key][index];
|
|
||||||
});
|
|
||||||
data_point.label = this.x[index];
|
|
||||||
return data_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_current_data_point(index) {
|
getDataPoint() {}
|
||||||
index = parseInt(index);
|
updateCurrentDataPoint() {}
|
||||||
if(index < 0) index = 0;
|
|
||||||
if(index >= this.x.length) index = this.x.length - 1;
|
|
||||||
if(index === this.current_index) return;
|
|
||||||
this.current_index = index;
|
|
||||||
$.fire(this.parent, "data-select", this.get_data_point());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Objects
|
|
||||||
setup_utils() { }
|
|
||||||
|
|
||||||
makeDrawAreaComponent(className, transform='') {
|
makeDrawAreaComponent(className, transform='') {
|
||||||
return makeSVGGroup(this.draw_area, className, transform);
|
return makeSVGGroup(this.draw_area, className, transform);
|
||||||
|
|||||||
@ -57,19 +57,19 @@ export default class LineChart extends AxisChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
make_paths() {
|
make_paths() {
|
||||||
this.y.map((d, i) => {
|
this.y.map(d => {
|
||||||
this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
|
this.make_path(d, this.x_axis_positions, d.y_tops, d.color || this.colors[d.index]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
make_path(d, i, x_positions, y_positions, color) {
|
make_path(d, x_positions, y_positions, color) {
|
||||||
let points_list = y_positions.map((y, i) => (x_positions[i] + ',' + y));
|
let points_list = y_positions.map((y, i) => (x_positions[i] + ',' + y));
|
||||||
let points_str = points_list.join("L");
|
let points_str = points_list.join("L");
|
||||||
|
|
||||||
this.paths_groups[i].textContent = '';
|
this.paths_groups[d.index].textContent = '';
|
||||||
|
|
||||||
d.path = makePath("M"+points_str, 'line-graph-path', color);
|
d.path = makePath("M"+points_str, 'line-graph-path', color);
|
||||||
this.paths_groups[i].appendChild(d.path);
|
this.paths_groups[d.index].appendChild(d.path);
|
||||||
|
|
||||||
if(this.heatline) {
|
if(this.heatline) {
|
||||||
let gradient_id = makeGradient(this.svg_defs, color);
|
let gradient_id = makeGradient(this.svg_defs, color);
|
||||||
@ -77,15 +77,15 @@ export default class LineChart extends AxisChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(this.region_fill) {
|
if(this.region_fill) {
|
||||||
this.fill_region_for_dataset(d, i, color, points_str);
|
this.fill_region_for_dataset(d, color, points_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_region_for_dataset(d, i, color, points_str) {
|
fill_region_for_dataset(d, color, points_str) {
|
||||||
let gradient_id = makeGradient(this.svg_defs, color, true);
|
let gradient_id = makeGradient(this.svg_defs, color, true);
|
||||||
let pathStr = "M" + `0,${this.zero_line}L` + points_str + `L${this.width},${this.zero_line}`;
|
let pathStr = "M" + `0,${this.zero_line}L` + points_str + `L${this.width},${this.zero_line}`;
|
||||||
|
|
||||||
d.regionPath = makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id})`);
|
d.regionPath = makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id})`);
|
||||||
this.paths_groups[i].appendChild(d.regionPath);
|
this.paths_groups[d.index].appendChild(d.regionPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { fillArray } from '../utils/helpers';
|
||||||
|
|
||||||
export function getBarHeightAndYAttr(yTop, zeroLine, totalHeight) {
|
export function getBarHeightAndYAttr(yTop, zeroLine, totalHeight) {
|
||||||
let height, y;
|
let height, y;
|
||||||
if (yTop <= zeroLine) {
|
if (yTop <= zeroLine) {
|
||||||
@ -21,3 +23,19 @@ export function getBarHeightAndYAttr(yTop, zeroLine, totalHeight) {
|
|||||||
|
|
||||||
return [height, y];
|
return [height, y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function equilizeNoOfPositions(old_x, old_y, new_x, new_y) {
|
||||||
|
let extra_count = new_x.length - old_x.length;
|
||||||
|
if(extra_count >= 0) {
|
||||||
|
// Substitute current unit set with a squiggled one (more units at end)
|
||||||
|
// in order to animate to stretch it later to new points
|
||||||
|
old_x = fillArray(old_x, extra_count);
|
||||||
|
old_y = fillArray(old_y, extra_count);
|
||||||
|
} else {
|
||||||
|
// Modify the new points to have extra points
|
||||||
|
// with the same position at end, old positions will squeeze in
|
||||||
|
new_x = fillArray(new_x, extra_count);
|
||||||
|
new_y = fillArray(new_y, extra_count);
|
||||||
|
}
|
||||||
|
return [old_x, old_y, new_x, new_y];
|
||||||
|
}
|
||||||
|
|||||||
@ -37,6 +37,22 @@ export function shuffle(array) {
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill an array with extra points
|
||||||
|
* @param {Array} array Array
|
||||||
|
* @param {Number} count number of filler elements
|
||||||
|
* @param {Object} element element to fill with
|
||||||
|
* @param {Boolean} start fill at start?
|
||||||
|
*/
|
||||||
|
export function fillArray(array, count, element, start=false) {
|
||||||
|
if(!element) {
|
||||||
|
element = start ? array[0] : array[array.length - 1];
|
||||||
|
}
|
||||||
|
let fillerArray = new Array(Math.abs(count)).fill(element);
|
||||||
|
array = start ? fillerArray.concat(array) : array.concat(fillerArray);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns pixel width of string.
|
* Returns pixel width of string.
|
||||||
* @param {String} string
|
* @param {String} string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user