chore: formatting changes
This commit is contained in:
parent
a839277732
commit
ddbd30ca07
@ -1,30 +1,47 @@
|
|||||||
import SvgTip from '../objects/SvgTip';
|
import SvgTip from "../objects/SvgTip";
|
||||||
import { $, isElementInViewport, getElementContentWidth, isHidden } from '../utils/dom';
|
import {
|
||||||
import { makeSVGContainer, makeSVGDefs, makeSVGGroup, makeText } from '../utils/draw';
|
$,
|
||||||
import { BASE_MEASURES, getExtraHeight, getExtraWidth, getTopOffset, getLeftOffset,
|
isElementInViewport,
|
||||||
INIT_CHART_UPDATE_TIMEOUT, CHART_POST_ANIMATE_TIMEOUT, DEFAULT_COLORS} from '../utils/constants';
|
getElementContentWidth,
|
||||||
import { getColor, isValidColor } from '../utils/colors';
|
isHidden,
|
||||||
import { runSMILAnimation } from '../utils/animation';
|
} from "../utils/dom";
|
||||||
import { downloadFile, prepareForExport } from '../utils/export';
|
import {
|
||||||
import { deepClone } from '../utils/helpers';
|
makeSVGContainer,
|
||||||
|
makeSVGDefs,
|
||||||
|
makeSVGGroup,
|
||||||
|
makeText,
|
||||||
|
} from "../utils/draw";
|
||||||
|
import {
|
||||||
|
BASE_MEASURES,
|
||||||
|
getExtraHeight,
|
||||||
|
getExtraWidth,
|
||||||
|
getTopOffset,
|
||||||
|
getLeftOffset,
|
||||||
|
INIT_CHART_UPDATE_TIMEOUT,
|
||||||
|
CHART_POST_ANIMATE_TIMEOUT,
|
||||||
|
DEFAULT_COLORS,
|
||||||
|
} from "../utils/constants";
|
||||||
|
import { getColor, isValidColor } from "../utils/colors";
|
||||||
|
import { runSMILAnimation } from "../utils/animation";
|
||||||
|
import { downloadFile, prepareForExport } from "../utils/export";
|
||||||
|
import { deepClone } from "../utils/helpers";
|
||||||
|
|
||||||
export default class BaseChart {
|
export default class BaseChart {
|
||||||
constructor(parent, options) {
|
constructor(parent, options) {
|
||||||
// deepclone options to avoid making changes to orignal object
|
// deepclone options to avoid making changes to orignal object
|
||||||
options = deepClone(options);
|
options = deepClone(options);
|
||||||
|
|
||||||
this.parent = typeof parent === 'string'
|
this.parent =
|
||||||
? document.querySelector(parent)
|
typeof parent === "string" ? document.querySelector(parent) : parent;
|
||||||
: parent;
|
|
||||||
|
|
||||||
if (!(this.parent instanceof HTMLElement)) {
|
if (!(this.parent instanceof HTMLElement)) {
|
||||||
throw new Error('No `parent` element to render on was provided.');
|
throw new Error("No `parent` element to render on was provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rawChartArgs = options;
|
this.rawChartArgs = options;
|
||||||
|
|
||||||
this.title = options.title || '';
|
this.title = options.title || "";
|
||||||
this.type = options.type || '';
|
this.type = options.type || "";
|
||||||
|
|
||||||
this.realData = this.prepareData(options.data);
|
this.realData = this.prepareData(options.data);
|
||||||
this.data = this.prepareFirstData(this.realData);
|
this.data = this.prepareFirstData(this.realData);
|
||||||
@ -35,15 +52,17 @@ export default class BaseChart {
|
|||||||
showTooltip: 1, // calculate
|
showTooltip: 1, // calculate
|
||||||
showLegend: 1, // calculate
|
showLegend: 1, // calculate
|
||||||
isNavigable: options.isNavigable || 0,
|
isNavigable: options.isNavigable || 0,
|
||||||
animate: (typeof options.animate !== 'undefined') ? options.animate : 1,
|
animate: typeof options.animate !== "undefined" ? options.animate : 1,
|
||||||
truncateLegends: options.truncateLegends || 1
|
truncateLegends: options.truncateLegends || 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.measures = JSON.parse(JSON.stringify(BASE_MEASURES));
|
this.measures = JSON.parse(JSON.stringify(BASE_MEASURES));
|
||||||
let m = this.measures;
|
let m = this.measures;
|
||||||
this.setMeasures(options);
|
this.setMeasures(options);
|
||||||
if(!this.title.length) { m.titleHeight = 0; }
|
if (!this.title.length) {
|
||||||
if(!this.config.showLegend) m.legendHeight = 0;
|
m.titleHeight = 0;
|
||||||
|
}
|
||||||
|
if (!this.config.showLegend) m.legendHeight = 0;
|
||||||
this.argHeight = options.height || m.baseHeight;
|
this.argHeight = options.height || m.baseHeight;
|
||||||
|
|
||||||
this.state = {};
|
this.state = {};
|
||||||
@ -51,7 +70,7 @@ export default class BaseChart {
|
|||||||
|
|
||||||
this.initTimeout = INIT_CHART_UPDATE_TIMEOUT;
|
this.initTimeout = INIT_CHART_UPDATE_TIMEOUT;
|
||||||
|
|
||||||
if(this.config.isNavigable) {
|
if (this.config.isNavigable) {
|
||||||
this.overlays = [];
|
this.overlays = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +90,7 @@ export default class BaseChart {
|
|||||||
colors = (colors || []).concat(DEFAULT_COLORS[type]);
|
colors = (colors || []).concat(DEFAULT_COLORS[type]);
|
||||||
colors.forEach((string) => {
|
colors.forEach((string) => {
|
||||||
const color = getColor(string);
|
const color = getColor(string);
|
||||||
if(!isValidColor(color)) {
|
if (!isValidColor(color)) {
|
||||||
console.warn('"' + string + '" is not a valid color.');
|
console.warn('"' + string + '" is not a valid color.');
|
||||||
} else {
|
} else {
|
||||||
validColors.push(color);
|
validColors.push(color);
|
||||||
@ -96,14 +115,14 @@ export default class BaseChart {
|
|||||||
this.resizeObserver = new ResizeObserver(this.boundDrawFn);
|
this.resizeObserver = new ResizeObserver(this.boundDrawFn);
|
||||||
this.resizeObserver.observe(this.parent);
|
this.resizeObserver.observe(this.parent);
|
||||||
}
|
}
|
||||||
window.addEventListener('resize', this.boundDrawFn);
|
window.addEventListener("resize", this.boundDrawFn);
|
||||||
window.addEventListener('orientationchange', this.boundDrawFn);
|
window.addEventListener("orientationchange", this.boundDrawFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
if (this.resizeObserver) this.resizeObserver.disconnect();
|
if (this.resizeObserver) this.resizeObserver.disconnect();
|
||||||
window.removeEventListener('resize', this.boundDrawFn);
|
window.removeEventListener("resize", this.boundDrawFn);
|
||||||
window.removeEventListener('orientationchange', this.boundDrawFn);
|
window.removeEventListener("orientationchange", this.boundDrawFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has to be called manually
|
// Has to be called manually
|
||||||
@ -117,31 +136,31 @@ export default class BaseChart {
|
|||||||
|
|
||||||
makeContainer() {
|
makeContainer() {
|
||||||
// Chart needs a dedicated parent element
|
// Chart needs a dedicated parent element
|
||||||
this.parent.innerHTML = '';
|
this.parent.innerHTML = "";
|
||||||
|
|
||||||
let args = {
|
let args = {
|
||||||
inside: this.parent,
|
inside: this.parent,
|
||||||
className: 'chart-container'
|
className: "chart-container",
|
||||||
};
|
};
|
||||||
|
|
||||||
if(this.independentWidth) {
|
if (this.independentWidth) {
|
||||||
args.styles = { width: this.independentWidth + 'px' };
|
args.styles = { width: this.independentWidth + "px" };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.container = $.create('div', args);
|
this.container = $.create("div", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
makeTooltip() {
|
makeTooltip() {
|
||||||
this.tip = new SvgTip({
|
this.tip = new SvgTip({
|
||||||
parent: this.container,
|
parent: this.container,
|
||||||
colors: this.colors
|
colors: this.colors,
|
||||||
});
|
});
|
||||||
this.bindTooltip();
|
this.bindTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
bindTooltip() {}
|
bindTooltip() {}
|
||||||
|
|
||||||
draw(onlyWidthChange=false, init=false) {
|
draw(onlyWidthChange = false, init = false) {
|
||||||
if (onlyWidthChange && isHidden(this.parent)) {
|
if (onlyWidthChange && isHidden(this.parent)) {
|
||||||
// Don't update anything if the chart is hidden
|
// Don't update anything if the chart is hidden
|
||||||
return;
|
return;
|
||||||
@ -152,13 +171,15 @@ export default class BaseChart {
|
|||||||
this.makeChartArea();
|
this.makeChartArea();
|
||||||
this.setupComponents();
|
this.setupComponents();
|
||||||
|
|
||||||
this.components.forEach(c => c.setup(this.drawArea));
|
this.components.forEach((c) => c.setup(this.drawArea));
|
||||||
// this.components.forEach(c => c.make());
|
// this.components.forEach(c => c.make());
|
||||||
this.render(this.components, false);
|
this.render(this.components, false);
|
||||||
|
|
||||||
if(init) {
|
if (init) {
|
||||||
this.data = this.realData;
|
this.data = this.realData;
|
||||||
setTimeout(() => {this.update(this.data);}, this.initTimeout);
|
setTimeout(() => {
|
||||||
|
this.update(this.data);
|
||||||
|
}, this.initTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.renderLegend();
|
this.renderLegend();
|
||||||
@ -174,50 +195,54 @@ export default class BaseChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
makeChartArea() {
|
makeChartArea() {
|
||||||
if(this.svg) {
|
if (this.svg) {
|
||||||
this.container.removeChild(this.svg);
|
this.container.removeChild(this.svg);
|
||||||
}
|
}
|
||||||
let m = this.measures;
|
let m = this.measures;
|
||||||
|
|
||||||
this.svg = makeSVGContainer(
|
this.svg = makeSVGContainer(
|
||||||
this.container,
|
this.container,
|
||||||
'frappe-chart chart',
|
"frappe-chart chart",
|
||||||
this.baseWidth,
|
this.baseWidth,
|
||||||
this.baseHeight
|
this.baseHeight
|
||||||
);
|
);
|
||||||
this.svgDefs = makeSVGDefs(this.svg);
|
this.svgDefs = makeSVGDefs(this.svg);
|
||||||
|
|
||||||
if(this.title.length) {
|
if (this.title.length) {
|
||||||
this.titleEL = makeText(
|
this.titleEL = makeText(
|
||||||
'title',
|
"title",
|
||||||
m.margins.left,
|
m.margins.left,
|
||||||
m.margins.top,
|
m.margins.top,
|
||||||
this.title,
|
this.title,
|
||||||
{
|
{
|
||||||
fontSize: m.titleFontSize,
|
fontSize: m.titleFontSize,
|
||||||
fill: '#666666',
|
fill: "#666666",
|
||||||
dy: m.titleFontSize
|
dy: m.titleFontSize,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let top = getTopOffset(m);
|
let top = getTopOffset(m);
|
||||||
this.drawArea = makeSVGGroup(
|
this.drawArea = makeSVGGroup(
|
||||||
this.type + '-chart chart-draw-area',
|
this.type + "-chart chart-draw-area",
|
||||||
`translate(${getLeftOffset(m)}, ${top})`
|
`translate(${getLeftOffset(m)}, ${top})`
|
||||||
);
|
);
|
||||||
|
|
||||||
if(this.config.showLegend) {
|
if (this.config.showLegend) {
|
||||||
top += this.height + m.paddings.bottom;
|
top += this.height + m.paddings.bottom;
|
||||||
this.legendArea = makeSVGGroup(
|
this.legendArea = makeSVGGroup(
|
||||||
'chart-legend',
|
"chart-legend",
|
||||||
`translate(${getLeftOffset(m)}, ${top})`
|
`translate(${getLeftOffset(m)}, ${top})`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.title.length) { this.svg.appendChild(this.titleEL); }
|
if (this.title.length) {
|
||||||
|
this.svg.appendChild(this.titleEL);
|
||||||
|
}
|
||||||
this.svg.appendChild(this.drawArea);
|
this.svg.appendChild(this.drawArea);
|
||||||
if(this.config.showLegend) { this.svg.appendChild(this.legendArea); }
|
if (this.config.showLegend) {
|
||||||
|
this.svg.appendChild(this.legendArea);
|
||||||
|
}
|
||||||
|
|
||||||
this.updateTipOffset(getLeftOffset(m), getTopOffset(m));
|
this.updateTipOffset(getLeftOffset(m), getTopOffset(m));
|
||||||
}
|
}
|
||||||
@ -225,15 +250,17 @@ export default class BaseChart {
|
|||||||
updateTipOffset(x, y) {
|
updateTipOffset(x, y) {
|
||||||
this.tip.offset = {
|
this.tip.offset = {
|
||||||
x: x,
|
x: x,
|
||||||
y: y
|
y: y,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setupComponents() { this.components = new Map(); }
|
setupComponents() {
|
||||||
|
this.components = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
update(data) {
|
update(data) {
|
||||||
if(!data) {
|
if (!data) {
|
||||||
console.error('No data to update.');
|
console.error("No data to update.");
|
||||||
}
|
}
|
||||||
this.data = this.prepareData(data);
|
this.data = this.prepareData(data);
|
||||||
this.calc(); // builds state
|
this.calc(); // builds state
|
||||||
@ -241,31 +268,31 @@ export default class BaseChart {
|
|||||||
this.renderLegend();
|
this.renderLegend();
|
||||||
}
|
}
|
||||||
|
|
||||||
render(components=this.components, animate=true) {
|
render(components = this.components, animate = true) {
|
||||||
if(this.config.isNavigable) {
|
if (this.config.isNavigable) {
|
||||||
// Remove all existing overlays
|
// Remove all existing overlays
|
||||||
this.overlays.map(o => o.parentNode.removeChild(o));
|
this.overlays.map((o) => o.parentNode.removeChild(o));
|
||||||
// ref.parentNode.insertBefore(element, ref);
|
// ref.parentNode.insertBefore(element, ref);
|
||||||
}
|
}
|
||||||
let elementsToAnimate = [];
|
let elementsToAnimate = [];
|
||||||
// Can decouple to this.refreshComponents() first to save animation timeout
|
// Can decouple to this.refreshComponents() first to save animation timeout
|
||||||
components.forEach(c => {
|
components.forEach((c) => {
|
||||||
elementsToAnimate = elementsToAnimate.concat(c.update(animate));
|
elementsToAnimate = elementsToAnimate.concat(c.update(animate));
|
||||||
});
|
});
|
||||||
if(elementsToAnimate.length > 0) {
|
if (elementsToAnimate.length > 0) {
|
||||||
runSMILAnimation(this.container, this.svg, elementsToAnimate);
|
runSMILAnimation(this.container, this.svg, elementsToAnimate);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
components.forEach(c => c.make());
|
components.forEach((c) => c.make());
|
||||||
this.updateNav();
|
this.updateNav();
|
||||||
}, CHART_POST_ANIMATE_TIMEOUT);
|
}, CHART_POST_ANIMATE_TIMEOUT);
|
||||||
} else {
|
} else {
|
||||||
components.forEach(c => c.make());
|
components.forEach((c) => c.make());
|
||||||
this.updateNav();
|
this.updateNav();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNav() {
|
updateNav() {
|
||||||
if(this.config.isNavigable) {
|
if (this.config.isNavigable) {
|
||||||
this.makeOverlay();
|
this.makeOverlay();
|
||||||
this.bindUnits();
|
this.bindUnits();
|
||||||
}
|
}
|
||||||
@ -273,24 +300,24 @@ export default class BaseChart {
|
|||||||
|
|
||||||
renderLegend() {}
|
renderLegend() {}
|
||||||
|
|
||||||
setupNavigation(init=false) {
|
setupNavigation(init = false) {
|
||||||
if(!this.config.isNavigable) return;
|
if (!this.config.isNavigable) return;
|
||||||
|
|
||||||
if(init) {
|
if (init) {
|
||||||
this.bindOverlay();
|
this.bindOverlay();
|
||||||
|
|
||||||
this.keyActions = {
|
this.keyActions = {
|
||||||
'13': this.onEnterKey.bind(this),
|
13: this.onEnterKey.bind(this),
|
||||||
'37': this.onLeftArrow.bind(this),
|
37: this.onLeftArrow.bind(this),
|
||||||
'38': this.onUpArrow.bind(this),
|
38: this.onUpArrow.bind(this),
|
||||||
'39': this.onRightArrow.bind(this),
|
39: this.onRightArrow.bind(this),
|
||||||
'40': this.onDownArrow.bind(this),
|
40: this.onDownArrow.bind(this),
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener('keydown', (e) => {
|
document.addEventListener("keydown", (e) => {
|
||||||
if(isElementInViewport(this.container)) {
|
if (isElementInViewport(this.container)) {
|
||||||
e = e || window.event;
|
e = e || window.event;
|
||||||
if(this.keyActions[e.keyCode]) {
|
if (this.keyActions[e.keyCode]) {
|
||||||
this.keyActions[e.keyCode]();
|
this.keyActions[e.keyCode]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,6 +346,6 @@ export default class BaseChart {
|
|||||||
|
|
||||||
export() {
|
export() {
|
||||||
let chartSvg = prepareForExport(this.svg);
|
let chartSvg = prepareForExport(this.svg);
|
||||||
downloadFile(this.title || 'Chart', [chartSvg]);
|
downloadFile(this.title || "Chart", [chartSvg]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user