chore: formatting changes

This commit is contained in:
Arjun Choudhary 2022-11-15 17:33:19 +05:30
parent a839277732
commit ddbd30ca07

View File

@ -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]);
} }
} }