Selaa lähdekoodia

chore: format codebase

pull/347/head
Shivam Mishra 4 vuotta sitten
vanhempi
commit
26671b143b
15 muutettua tiedostoa jossa 277 lisäystä ja 271 poistoa
  1. +37
    -37
      src/js/charts/BaseChart.js
  2. +31
    -27
      src/js/charts/Heatmap.js
  3. +5
    -5
      src/js/charts/PercentageChart.js
  4. +0
    -1
      src/js/charts/PieChart.js
  5. +24
    -22
      src/js/objects/ChartComponents.js
  6. +12
    -12
      src/js/utils/animate.js
  7. +9
    -9
      src/js/utils/animation.js
  8. +23
    -21
      src/js/utils/axis-chart-utils.js
  9. +7
    -7
      src/js/utils/date-utils.js
  10. +14
    -15
      src/js/utils/dom.js
  11. +10
    -10
      src/js/utils/draw-utils.js
  12. +66
    -66
      src/js/utils/draw.js
  13. +2
    -2
      src/js/utils/export.js
  14. +7
    -7
      src/js/utils/helpers.js
  15. +30
    -30
      src/js/utils/intervals.js

+ 37
- 37
src/js/charts/BaseChart.js Näytä tiedosto

@@ -42,8 +42,8 @@ export default class BaseChart {
this.measures = JSON.parse(JSON.stringify(BASE_MEASURES));
let m = this.measures;
this.setMeasures(options);
if(!this.title.length) { m.titleHeight = 0; }
if(!this.config.showLegend) m.legendHeight = 0;
if (!this.title.length) { m.titleHeight = 0; }
if (!this.config.showLegend) m.legendHeight = 0;
this.argHeight = options.height || m.baseHeight;

this.state = {};
@@ -51,7 +51,7 @@ export default class BaseChart {

this.initTimeout = INIT_CHART_UPDATE_TIMEOUT;

if(this.config.isNavigable) {
if (this.config.isNavigable) {
this.overlays = [];
}

@@ -71,7 +71,7 @@ export default class BaseChart {
colors = (colors || []).concat(DEFAULT_COLORS[type]);
colors.forEach((string) => {
const color = getColor(string);
if(!isValidColor(color)) {
if (!isValidColor(color)) {
console.warn('"' + string + '" is not a valid color.');
} else {
validColors.push(color);
@@ -119,7 +119,7 @@ export default class BaseChart {
className: 'chart-container'
};

if(this.independentWidth) {
if (this.independentWidth) {
args.styles = { width: this.independentWidth + 'px' };
}

@@ -134,9 +134,9 @@ export default class BaseChart {
this.bindTooltip();
}

bindTooltip() {}
bindTooltip() { }

draw(onlyWidthChange=false, init=false) {
draw(onlyWidthChange = false, init = false) {
if (onlyWidthChange && isHidden(this.parent)) {
// Don't update anything if the chart is hidden
return;
@@ -151,9 +151,9 @@ export default class BaseChart {
// this.components.forEach(c => c.make());
this.render(this.components, false);

if(init) {
if (init) {
this.data = this.realData;
setTimeout(() => {this.update(this.data);}, this.initTimeout);
setTimeout(() => { this.update(this.data); }, this.initTimeout);
}

this.renderLegend();
@@ -161,7 +161,7 @@ export default class BaseChart {
this.setupNavigation(init);
}

calc() {} // builds state
calc() { } // builds state

updateWidth() {
this.baseWidth = getElementContentWidth(this.parent);
@@ -169,7 +169,7 @@ export default class BaseChart {
}

makeChartArea() {
if(this.svg) {
if (this.svg) {
this.container.removeChild(this.svg);
}
let m = this.measures;
@@ -182,7 +182,7 @@ export default class BaseChart {
);
this.svgDefs = makeSVGDefs(this.svg);

if(this.title.length) {
if (this.title.length) {
this.titleEL = makeText(
'title',
m.margins.left,
@@ -202,7 +202,7 @@ export default class BaseChart {
`translate(${getLeftOffset(m)}, ${top})`
);

if(this.config.showLegend) {
if (this.config.showLegend) {
top += this.height + m.paddings.bottom;
this.legendArea = makeSVGGroup(
'chart-legend',
@@ -210,9 +210,9 @@ export default class BaseChart {
);
}

if(this.title.length) { this.svg.appendChild(this.titleEL); }
if (this.title.length) { this.svg.appendChild(this.titleEL); }
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));
}
@@ -227,7 +227,7 @@ export default class BaseChart {
setupComponents() { this.components = new Map(); }

update(data) {
if(!data) {
if (!data) {
console.error('No data to update.');
}
this.data = this.prepareData(data);
@@ -235,8 +235,8 @@ export default class BaseChart {
this.render(this.components, this.config.animate);
}

render(components=this.components, animate=true) {
if(this.config.isNavigable) {
render(components = this.components, animate = true) {
if (this.config.isNavigable) {
// Remove all existing overlays
this.overlays.map(o => o.parentNode.removeChild(o));
// ref.parentNode.insertBefore(element, ref);
@@ -246,7 +246,7 @@ export default class BaseChart {
components.forEach(c => {
elementsToAnimate = elementsToAnimate.concat(c.update(animate));
});
if(elementsToAnimate.length > 0) {
if (elementsToAnimate.length > 0) {
runSMILAnimation(this.container, this.svg, elementsToAnimate);
setTimeout(() => {
components.forEach(c => c.make());
@@ -259,7 +259,7 @@ export default class BaseChart {
}

updateNav() {
if(this.config.isNavigable) {
if (this.config.isNavigable) {
this.makeOverlay();
this.bindUnits();
}
@@ -289,7 +289,7 @@ export default class BaseChart {
setupNavigation(init = false) {
if (!this.config.isNavigable) return;

if(init) {
if (init) {
this.bindOverlay();

this.keyActions = {
@@ -301,9 +301,9 @@ export default class BaseChart {
};

document.addEventListener('keydown', (e) => {
if(isElementInViewport(this.container)) {
if (isElementInViewport(this.container)) {
e = e || window.event;
if(this.keyActions[e.keyCode]) {
if (this.keyActions[e.keyCode]) {
this.keyActions[e.keyCode]();
}
}
@@ -311,24 +311,24 @@ export default class BaseChart {
}
}

makeOverlay() {}
updateOverlay() {}
bindOverlay() {}
bindUnits() {}
makeOverlay() { }
updateOverlay() { }
bindOverlay() { }
bindUnits() { }

onLeftArrow() {}
onRightArrow() {}
onUpArrow() {}
onDownArrow() {}
onEnterKey() {}
onLeftArrow() { }
onRightArrow() { }
onUpArrow() { }
onDownArrow() { }
onEnterKey() { }

addDataPoint() {}
removeDataPoint() {}
addDataPoint() { }
removeDataPoint() { }

getDataPoint() {}
setCurrentDataPoint() {}
getDataPoint() { }
setCurrentDataPoint() { }

updateDataset() {}
updateDataset() { }

export() {
let chartSvg = prepareForExport(this.svg);


+ 31
- 27
src/js/charts/Heatmap.js Näytä tiedosto

@@ -1,11 +1,15 @@
import BaseChart from './BaseChart';
import { getComponent } from '../objects/ChartComponents';
import { makeText, heatSquare } from '../utils/draw';
import { DAY_NAMES_SHORT, addDays, areInSameMonth, getLastDateInMonth, setDayToSunday, getYyyyMmDd, getWeeksBetween, getMonthName, clone,
NO_OF_MILLIS, NO_OF_YEAR_MONTHS, NO_OF_DAYS_IN_WEEK } from '../utils/date-utils';
import {
DAY_NAMES_SHORT, addDays, areInSameMonth, getLastDateInMonth, setDayToSunday, getYyyyMmDd, getWeeksBetween, getMonthName, clone,
NO_OF_MILLIS, NO_OF_YEAR_MONTHS, NO_OF_DAYS_IN_WEEK
} from '../utils/date-utils';
import { calcDistribution, getMaxCheckpoint } from '../utils/intervals';
import { getExtraHeight, getExtraWidth, HEATMAP_DISTRIBUTION_SIZE, HEATMAP_SQUARE_SIZE,
HEATMAP_GUTTER_SIZE } from '../utils/constants';
import {
getExtraHeight, getExtraWidth, HEATMAP_DISTRIBUTION_SIZE, HEATMAP_SQUARE_SIZE,
HEATMAP_GUTTER_SIZE
} from '../utils/constants';

const COL_WIDTH = HEATMAP_SQUARE_SIZE + HEATMAP_GUTTER_SIZE;
const ROW_HEIGHT = COL_WIDTH;
@@ -49,19 +53,19 @@ export default class Heatmap extends BaseChart {
+ getExtraWidth(this.measures);
}

prepareData(data=this.data) {
if(data.start && data.end && data.start > data.end) {
prepareData(data = this.data) {
if (data.start && data.end && data.start > data.end) {
throw new Error('Start date cannot be greater than end date.');
}

if(!data.start) {
if (!data.start) {
data.start = new Date();
data.start.setFullYear( data.start.getFullYear() - 1 );
data.start.setFullYear(data.start.getFullYear() - 1);
}
if(!data.end) { data.end = new Date(); }
if (!data.end) { data.end = new Date(); }
data.dataPoints = data.dataPoints || {};

if(parseInt(Object.keys(data.dataPoints)[0]) > 100000) {
if (parseInt(Object.keys(data.dataPoints)[0]) > 100000) {
let points = {};
Object.keys(data.dataPoints).forEach(timestampSec => {
let date = new Date(timestampSec * NO_OF_MILLIS);
@@ -105,7 +109,7 @@ export default class Heatmap extends BaseChart {
.reduce((a, b) => a + b, 0)
* COL_WIDTH
},
function() {
function () {
return s.domainConfigs[i];
}.bind(this)

@@ -120,8 +124,8 @@ export default class Heatmap extends BaseChart {

let y = 0;
DAY_NAMES_SHORT.forEach((dayName, i) => {
if([1, 3, 5].includes(i)) {
let dayText = makeText('subdomain-name', -COL_WIDTH/2, y, dayName,
if ([1, 3, 5].includes(i)) {
let dayText = makeText('subdomain-name', -COL_WIDTH / 2, y, dayName,
{
fontSize: HEATMAP_SQUARE_SIZE,
dy: 8,
@@ -135,7 +139,7 @@ export default class Heatmap extends BaseChart {
}

update(data) {
if(!data) {
if (!data) {
console.error('No data to update.');
}

@@ -149,22 +153,22 @@ export default class Heatmap extends BaseChart {
this.components.forEach(comp => {
let daySquares = comp.store;
let daySquare = e.target;
if(daySquares.includes(daySquare)) {
if (daySquares.includes(daySquare)) {

let count = daySquare.getAttribute('data-value');
let dateParts = daySquare.getAttribute('data-date').split('-');

let month = getMonthName(parseInt(dateParts[1])-1, true);
let month = getMonthName(parseInt(dateParts[1]) - 1, true);

let gOff = this.container.getBoundingClientRect(), pOff = daySquare.getBoundingClientRect();

let width = parseInt(e.target.getAttribute('width'));
let x = pOff.left - gOff.left + width/2;
let x = pOff.left - gOff.left + width / 2;
let y = pOff.top - gOff.top;
let value = count + ' ' + this.countLabel;
let name = ' on ' + month + ' ' + dateParts[0] + ', ' + dateParts[2];

this.tip.setValues(x, y, {name: name, value: value, valueFirst: 1}, []);
this.tip.setValues(x, y, { name: name, value: value, valueFirst: 1 }, []);
this.tip.showTip();
}
});
@@ -183,7 +187,7 @@ export default class Heatmap extends BaseChart {
dy: 9
}
);
x = (COL_WIDTH * 2) + COL_WIDTH/2;
x = (COL_WIDTH * 2) + COL_WIDTH / 2;
this.legendArea.appendChild(lessText);

this.colors.slice(0, HEATMAP_DISTRIBUTION_SIZE).map((color, i) => {
@@ -192,7 +196,7 @@ export default class Heatmap extends BaseChart {
this.legendArea.appendChild(square);
});

let moreTextX = x + HEATMAP_DISTRIBUTION_SIZE * (COL_WIDTH + 3) + COL_WIDTH/4;
let moreTextX = x + HEATMAP_DISTRIBUTION_SIZE * (COL_WIDTH + 3) + COL_WIDTH / 4;
let moreText = makeText('subdomain-name', moreTextX, y, 'More',
{
fontSize: HEATMAP_SQUARE_SIZE + 1,
@@ -212,9 +216,9 @@ export default class Heatmap extends BaseChart {
let domainConfigs = [];

let startOfMonth = clone(s.start);
for(var i = 0; i < noOfMonths; i++) {
for (var i = 0; i < noOfMonths; i++) {
let endDate = s.end;
if(!areInSameMonth(startOfMonth, s.end)) {
if (!areInSameMonth(startOfMonth, s.end)) {
let [month, year] = [startOfMonth.getMonth(), startOfMonth.getFullYear()];
endDate = getLastDateInMonth(month, year);
}
@@ -227,7 +231,7 @@ export default class Heatmap extends BaseChart {
return domainConfigs;
}

getDomainConfig(startDate, endDate='') {
getDomainConfig(startDate, endDate = '') {
let [month, year] = [startDate.getMonth(), startDate.getFullYear()];
let startOfWeek = setDayToSunday(startDate); // TODO: Monday as well
endDate = clone(endDate) || getLastDateInMonth(month, year);
@@ -241,7 +245,7 @@ export default class Heatmap extends BaseChart {
let noOfMonthWeeks = getWeeksBetween(startOfWeek, endDate);

let cols = [], col;
for(var i = 0; i < noOfMonthWeeks; i++) {
for (var i = 0; i < noOfMonthWeeks; i++) {
col = this.getCol(startOfWeek, month);
cols.push(col);

@@ -249,7 +253,7 @@ export default class Heatmap extends BaseChart {
addDays(startOfWeek, 1);
}

if(col[NO_OF_DAYS_IN_WEEK - 1].dataValue !== undefined) {
if (col[NO_OF_DAYS_IN_WEEK - 1].dataValue !== undefined) {
addDays(startOfWeek, 1);
cols.push(this.getCol(startOfWeek, month, true));
}
@@ -266,13 +270,13 @@ export default class Heatmap extends BaseChart {
let currentDate = clone(startDate);
let col = [];

for(var i = 0; i < NO_OF_DAYS_IN_WEEK; i++, addDays(currentDate, 1)) {
for (var i = 0; i < NO_OF_DAYS_IN_WEEK; i++, addDays(currentDate, 1)) {
let config = {};

// Non-generic adjustment for entire heatmap, needs state
let currentDateWithinData = currentDate >= s.start && currentDate <= s.end;

if(empty || currentDate.getMonth() !== month || !currentDateWithinData) {
if (empty || currentDate.getMonth() !== month || !currentDateWithinData) {
config.yyyyMmDd = getYyyyMmDd(currentDate);
} else {
config = this.getSubDomainConfig(currentDate);


+ 5
- 5
src/js/charts/PercentageChart.js Näytä tiedosto

@@ -34,7 +34,7 @@ export default class PercentageChart extends AggregationChart {
{
barHeight: this.barOptions.height,
},
function() {
function () {
return {
xPositions: s.xPositions,
widths: s.widths,
@@ -80,13 +80,13 @@ export default class PercentageChart extends AggregationChart {

let width = bar.getAttribute('width') || bar.getBoundingClientRect().width;

let x = pOff.left - gOff.left + parseInt(width)/2;
let x = pOff.left - gOff.left + parseInt(width) / 2;
let y = pOff.top - gOff.top;
let title = (this.formattedLabels && this.formattedLabels.length>0
let title = (this.formattedLabels && this.formattedLabels.length > 0
? this.formattedLabels[i] : this.state.labels[i]) + ': ';
let fraction = s.sliceTotals[i]/s.grandTotal;
let fraction = s.sliceTotals[i] / s.grandTotal;

this.tip.setValues(x, y, {name: title, value: (fraction*100).toFixed(1) + "%"});
this.tip.setValues(x, y, { name: title, value: (fraction * 100).toFixed(1) + "%" });
this.tip.showTip();
}
});


+ 0
- 1
src/js/charts/PieChart.js Näytä tiedosto

@@ -3,7 +3,6 @@ import { getComponent } from '../objects/ChartComponents';
import { getOffset } from '../utils/dom';
import { getPositionByAngle } from '../utils/helpers';
import { makeArcPathStr, makeCircleStr } from '../utils/draw';
import { lightenDarkenColor } from '../utils/colors';
import { transform } from '../utils/animation';
import { FULL_ANGLE } from '../utils/constants';



+ 24
- 22
src/js/objects/ChartComponents.js Näytä tiedosto

@@ -1,8 +1,10 @@
import { makeSVGGroup } from '../utils/draw';
import { makeText, makePath, xLine, yLine, yMarker, yRegion, datasetBar, datasetDot, percentageBar, getPaths, heatSquare } from '../utils/draw';
import { equilizeNoOfElements } from '../utils/draw-utils';
import { translateHoriLine, translateVertLine, animateRegion, animateBar,
animateDot, animatePath, animatePathStr } from '../utils/animate';
import {
translateHoriLine, translateVertLine, animateRegion, animateBar,
animateDot, animatePath, animatePathStr
} from '../utils/animate';
import { getMonthName } from '../utils/date-utils';

class ChartComponent {
@@ -27,7 +29,7 @@ class ChartComponent {
this.labels = [];

this.layerClass = layerClass;
this.layerClass = typeof(this.layerClass) === 'function'
this.layerClass = typeof (this.layerClass) === 'function'
? this.layerClass() : this.layerClass;

this.refresh();
@@ -61,7 +63,7 @@ class ChartComponent {
update(animate = true) {
this.refresh();
let animateElements = [];
if(animate) {
if (animate) {
animateElements = this.animateElements(this.data) || [];
}
return animateElements;
@@ -86,7 +88,7 @@ let componentConfigs = {
pieSlices: {
layerClass: 'pie-slices',
makeElements(data) {
return data.sliceStrings.map((s, i) =>{
return data.sliceStrings.map((s, i) => {
let slice = makePath(s, 'pie-path', 'none', data.colors[i]);
slice.style.transition = 'transform .3s;';
return slice;
@@ -103,7 +105,7 @@ let componentConfigs = {
layerClass: 'percentage-bars',
makeElements(data) {
const numberOfPoints = data.xPositions.length;
return data.xPositions.map((x, i) =>{
return data.xPositions.map((x, i) => {
let y = 0;

let isLast = i == numberOfPoints - 1;
@@ -115,7 +117,7 @@ let componentConfigs = {
},

animateElements(newData) {
if(newData) return [];
if (newData) return [];
}
},
yAxis: {
@@ -123,7 +125,7 @@ let componentConfigs = {
makeElements(data) {
return data.positions.map((position, i) =>
yLine(position, data.labels[i], this.constants.width,
{mode: this.constants.mode, pos: this.constants.pos, shortenNumbers: this.constants.shortenNumbers})
{ mode: this.constants.mode, pos: this.constants.pos, shortenNumbers: this.constants.shortenNumbers })
);
},

@@ -154,7 +156,7 @@ let componentConfigs = {
makeElements(data) {
return data.positions.map((position, i) =>
xLine(position, data.calcLabels[i], this.constants.height,
{mode: this.constants.mode, pos: this.constants.pos})
{ mode: this.constants.mode, pos: this.constants.pos })
);
},

@@ -218,7 +220,7 @@ let componentConfigs = {
makeElements(data) {
return data.map(r =>
yRegion(r.startPos, r.endPos, this.constants.width,
r.label, {labelPos: r.options.labelPos})
r.label, { labelPos: r.options.labelPos })
);
},
animateElements(newData) {
@@ -254,16 +256,16 @@ let componentConfigs = {
},

heatDomain: {
layerClass: function() { return 'heat-domain domain-' + this.constants.index; },
layerClass: function () { return 'heat-domain domain-' + this.constants.index; },
makeElements(data) {
let {index, colWidth, rowHeight, squareSize, radius, xTranslate} = this.constants;
let { index, colWidth, rowHeight, squareSize, radius, xTranslate } = this.constants;
let monthNameHeight = -12;
let x = xTranslate, y = 0;

this.serializedSubDomains = [];

data.cols.map((week, weekNo) => {
if(weekNo === 1) {
if (weekNo === 1) {
this.labels.push(
makeText('domain-name', x, monthNameHeight, getMonthName(index, true).toUpperCase(),
{
@@ -273,7 +275,7 @@ let componentConfigs = {
);
}
week.map((day, i) => {
if(day.fill) {
if (day.fill) {
let data = {
'data-date': day.yyyyMmDd,
'data-value': day.dataValue,
@@ -292,12 +294,12 @@ let componentConfigs = {
},

animateElements(newData) {
if(newData) return [];
if (newData) return [];
}
},

barGraph: {
layerClass: function() { return 'dataset-units dataset-bars dataset-' + this.constants.index; },
layerClass: function () { return 'dataset-units dataset-bars dataset-' + this.constants.index; },
makeElements(data) {
let c = this.constants;
this.unitType = 'bar';
@@ -351,7 +353,7 @@ let componentConfigs = {
this.store.map((bar, i) => {
animateElements = animateElements.concat(animateBar(
bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i],
{zeroLine: newData.zeroLine}
{ zeroLine: newData.zeroLine }
));
});

@@ -360,12 +362,12 @@ let componentConfigs = {
},

lineGraph: {
layerClass: function() { return 'dataset-units dataset-line dataset-' + this.constants.index; },
layerClass: function () { return 'dataset-units dataset-line dataset-' + this.constants.index; },
makeElements(data) {
let c = this.constants;
this.unitType = 'dot';
this.paths = {};
if(!c.hideLine) {
if (!c.hideLine) {
this.paths = getPaths(
data.xPositions,
data.yPositions,
@@ -383,7 +385,7 @@ let componentConfigs = {
}

this.units = [];
if(c.showDots) {
if (c.showDots) {
this.units = data.yPositions.map((y, j) => {
return datasetDot(
data.xPositions[j],
@@ -422,12 +424,12 @@ let componentConfigs = {

let animateElements = [];

if(Object.keys(this.paths).length) {
if (Object.keys(this.paths).length) {
animateElements = animateElements.concat(animatePath(
this.paths, newXPos, newYPos, newData.zeroLine, this.constants.spline));
}

if(this.units.length) {
if (this.units.length) {
this.units.map((dot, i) => {
animateElements = animateElements.concat(animateDot(
dot, newXPos[i], newYPos[i]));


+ 12
- 12
src/js/utils/animate.js Näytä tiedosto

@@ -11,11 +11,11 @@ export function translate(unit, oldCoord, newCoord, duration) {
let old = typeof oldCoord === 'string' ? oldCoord : oldCoord.join(', ');
return [
unit,
{transform: newCoord.join(', ')},
{ transform: newCoord.join(', ') },
duration,
STD_EASING,
"translate",
{transform: old}
{ transform: old }
];
}

@@ -42,14 +42,14 @@ export function animateRegion(rectGroup, newY1, newY2, oldY2) {
return [rectAnim, groupAnim];
}

export function animateBar(bar, x, yTop, width, offset=0, meta={}) {
export function animateBar(bar, x, yTop, width, offset = 0, meta = {}) {
let [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine);
y -= offset;
if(bar.nodeName !== 'rect') {
if (bar.nodeName !== 'rect') {
let rect = bar.childNodes[0];
let rectAnim = [
rect,
{width: width, height: height},
{ width: width, height: height },
UNIT_ANIM_DUR,
STD_EASING
];
@@ -58,18 +58,18 @@ export function animateBar(bar, x, yTop, width, offset=0, meta={}) {
let groupAnim = translate(bar, oldCoordStr, [x, y], MARKER_LINE_ANIM_DUR);
return [rectAnim, groupAnim];
} else {
return [[bar, {width: width, height: height, x: x, y: y}, UNIT_ANIM_DUR, STD_EASING]];
return [[bar, { width: width, height: height, x: x, y: y }, UNIT_ANIM_DUR, STD_EASING]];
}
// bar.animate({height: args.newHeight, y: yTop}, UNIT_ANIM_DUR, mina.easein);
}

export function animateDot(dot, x, y) {
if(dot.nodeName !== 'circle') {
if (dot.nodeName !== 'circle') {
let oldCoordStr = dot.getAttribute("transform").split("(")[1].slice(0, -1);
let groupAnim = translate(dot, oldCoordStr, [x, y], MARKER_LINE_ANIM_DUR);
return [groupAnim];
} else {
return [[dot, {cx: x, cy: y}, UNIT_ANIM_DUR, STD_EASING]];
return [[dot, { cx: x, cy: y }, UNIT_ANIM_DUR, STD_EASING]];
}
// dot.animate({cy: yTop}, UNIT_ANIM_DUR, mina.easein);
}
@@ -81,16 +81,16 @@ export function animatePath(paths, newXList, newYList, zeroLine, spline) {
if (spline)
pointsStr = getSplineCurvePointsStr(newXList, newYList);

const animPath = [paths.path, {d:"M" + pointsStr}, PATH_ANIM_DUR, STD_EASING];
const animPath = [paths.path, { d: "M" + pointsStr }, PATH_ANIM_DUR, STD_EASING];
pathComponents.push(animPath);

if(paths.region) {
if (paths.region) {
let regStartPt = `${newXList[0]},${zeroLine}L`;
let regEndPt = `L${newXList.slice(-1)[0]}, ${zeroLine}`;

const animRegion = [
paths.region,
{d:"M" + regStartPt + pointsStr + regEndPt},
{ d: "M" + regStartPt + pointsStr + regEndPt },
PATH_ANIM_DUR,
STD_EASING
];
@@ -101,5 +101,5 @@ export function animatePath(paths, newXList, newYList, zeroLine, spline) {
}

export function animatePathStr(oldPath, pathStr) {
return [oldPath, {d: pathStr}, UNIT_ANIM_DUR, STD_EASING];
return [oldPath, { d: pathStr }, UNIT_ANIM_DUR, STD_EASING];
}

+ 9
- 9
src/js/utils/animation.js Näytä tiedosto

@@ -11,14 +11,14 @@ const EASING = {
easeinout: "0.42 0 0.58 1"
};

function animateSVGElement(element, props, dur, easingType="linear", type=undefined, oldValues={}) {
function animateSVGElement(element, props, dur, easingType = "linear", type = undefined, oldValues = {}) {

let animElement = element.cloneNode(true);
let newElement = element.cloneNode(true);

for(var attributeName in props) {
for (var attributeName in props) {
let animateElement;
if(attributeName === 'transform') {
if (attributeName === 'transform') {
animateElement = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");
} else {
animateElement = document.createElementNS("http://www.w3.org/2000/svg", "animate");
@@ -31,7 +31,7 @@ function animateSVGElement(element, props, dur, easingType="linear", type=undefi
from: currentValue,
to: value,
begin: "0s",
dur: dur/1000 + "s",
dur: dur / 1000 + "s",
values: currentValue + ";" + value,
keySplines: EASING[easingType],
keyTimes: "0;1",
@@ -39,7 +39,7 @@ function animateSVGElement(element, props, dur, easingType="linear", type=undefi
fill: 'freeze'
};

if(type) {
if (type) {
animAttr["type"] = type;
}

@@ -49,7 +49,7 @@ function animateSVGElement(element, props, dur, easingType="linear", type=undefi

animElement.appendChild(animateElement);

if(type) {
if (type) {
newElement.setAttribute(attributeName, `translate(${value})`);
} else {
newElement.setAttribute(attributeName, value);
@@ -97,10 +97,10 @@ function animateSVG(svgContainer, elements) {
}

export function runSMILAnimation(parent, svgElement, elementsToAnimate) {
if(elementsToAnimate.length === 0) return;
if (elementsToAnimate.length === 0) return;

let animSvgElement = animateSVG(svgElement, elementsToAnimate);
if(svgElement.parentNode == parent) {
if (svgElement.parentNode == parent) {
parent.removeChild(svgElement);
parent.appendChild(animSvgElement);

@@ -108,7 +108,7 @@ export function runSMILAnimation(parent, svgElement, elementsToAnimate) {

// Replace the new svgElement (data has already been replaced)
setTimeout(() => {
if(animSvgElement.parentNode == parent) {
if (animSvgElement.parentNode == parent) {
parent.removeChild(animSvgElement);
parent.appendChild(svgElement);
}


+ 23
- 21
src/js/utils/axis-chart-utils.js Näytä tiedosto

@@ -1,6 +1,8 @@
import { fillArray } from '../utils/helpers';
import { DEFAULT_AXIS_CHART_TYPE, AXIS_DATASET_CHART_TYPES, DEFAULT_CHAR_WIDTH,
SERIES_LABEL_SPACE_RATIO } from '../utils/constants';
import {
DEFAULT_AXIS_CHART_TYPE, AXIS_DATASET_CHART_TYPES, DEFAULT_CHAR_WIDTH,
SERIES_LABEL_SPACE_RATIO
} from '../utils/constants';

export function dataPrep(data, type) {
data.labels = data.labels || [];
@@ -10,16 +12,16 @@ export function dataPrep(data, type) {
// Datasets
let datasets = data.datasets;
let zeroArray = new Array(datasetLength).fill(0);
if(!datasets) {
if (!datasets) {
// default
datasets = [{
values: zeroArray
}];
}

datasets.map(d=> {
datasets.map(d => {
// Set values
if(!d.values) {
if (!d.values) {
d.values = zeroArray;
} else {
// Check for non values
@@ -27,7 +29,7 @@ export function dataPrep(data, type) {
vals = vals.map(val => (!isNaN(val) ? val : 0));

// Trim or extend
if(vals.length > datasetLength) {
if (vals.length > datasetLength) {
vals = vals.slice(0, datasetLength);
} else {
vals = fillArray(vals, datasetLength - vals.length, 0);
@@ -38,8 +40,8 @@ export function dataPrep(data, type) {
//

// Set type
if(!d.chartType ) {
if(!AXIS_DATASET_CHART_TYPES.includes(type)) type === DEFAULT_AXIS_CHART_TYPE;
if (!d.chartType) {
if (!AXIS_DATASET_CHART_TYPES.includes(type)) type === DEFAULT_AXIS_CHART_TYPE;
d.chartType = type;
}

@@ -49,9 +51,9 @@ export function dataPrep(data, type) {

// Regions
// data.yRegions = data.yRegions || [];
if(data.yRegions) {
if (data.yRegions) {
data.yRegions.map(d => {
if(d.end < d.start) {
if (d.end < d.start) {
[d.start, d.end] = [d.end, d.start];
}
});
@@ -75,7 +77,7 @@ export function zeroDataPrep(realData) {
}),
};

if(realData.yMarkers) {
if (realData.yMarkers) {
zeroData.yMarkers = [
{
value: 0,
@@ -84,7 +86,7 @@ export function zeroDataPrep(realData) {
];
}

if(realData.yRegions) {
if (realData.yRegions) {
zeroData.yRegions = [
{
start: 0,
@@ -97,30 +99,30 @@ export function zeroDataPrep(realData) {
return zeroData;
}

export function getShortenedLabels(chartWidth, labels=[], isSeries=true) {
export function getShortenedLabels(chartWidth, labels = [], isSeries = true) {
let allowedSpace = (chartWidth / labels.length) * SERIES_LABEL_SPACE_RATIO;
if(allowedSpace <= 0) allowedSpace = 1;
if (allowedSpace <= 0) allowedSpace = 1;
let allowedLetters = allowedSpace / DEFAULT_CHAR_WIDTH;

let seriesMultiple;
if(isSeries) {
if (isSeries) {
// Find the maximum label length for spacing calculations
let maxLabelLength = Math.max(...labels.map(label => label.length));
seriesMultiple = Math.ceil(maxLabelLength/allowedLetters);
seriesMultiple = Math.ceil(maxLabelLength / allowedLetters);
}

let calcLabels = labels.map((label, i) => {
label += "";
if(label.length > allowedLetters) {
if (label.length > allowedLetters) {

if(!isSeries) {
if(allowedLetters-3 > 0) {
label = label.slice(0, allowedLetters-3) + " ...";
if (!isSeries) {
if (allowedLetters - 3 > 0) {
label = label.slice(0, allowedLetters - 3) + " ...";
} else {
label = label.slice(0, allowedLetters) + '..';
}
} else {
if(i % seriesMultiple !== 0 && i !== (labels.length - 1)) {
if (i % seriesMultiple !== 0 && i !== (labels.length - 1)) {
label = "";
}
}


+ 7
- 7
src/js/utils/date-utils.js Näytä tiedosto

@@ -27,8 +27,8 @@ export function getYyyyMmDd(date) {
let mm = date.getMonth() + 1; // getMonth() is zero-based
return [
date.getFullYear(),
(mm>9 ? '' : '0') + mm,
(dd>9 ? '' : '0') + dd
(mm > 9 ? '' : '0') + mm,
(dd > 9 ? '' : '0') + dd
].join('-');
}

@@ -37,12 +37,12 @@ export function clone(date) {
}

export function timestampSec(date) {
return date.getTime()/NO_OF_MILLIS;
return date.getTime() / NO_OF_MILLIS;
}

export function timestampToMidnight(timestamp, roundAhead = false) {
let midnightTs = Math.floor(timestamp - (timestamp % SEC_IN_DAY));
if(roundAhead) {
if (roundAhead) {
return midnightTs + SEC_IN_DAY;
}
return midnightTs;
@@ -65,12 +65,12 @@ export function areInSameMonth(startDate, endDate) {
&& startDate.getFullYear() === endDate.getFullYear();
}

export function getMonthName(i, short=false) {
export function getMonthName(i, short = false) {
let monthName = MONTH_NAMES[i];
return short ? monthName.slice(0, 3) : monthName;
}

export function getLastDateInMonth (month, year) {
export function getLastDateInMonth(month, year) {
return new Date(year, month + 1, 0); // 0: last day in previous month
}

@@ -78,7 +78,7 @@ export function getLastDateInMonth (month, year) {
export function setDayToSunday(date) {
let newDate = clone(date);
const day = newDate.getDay();
if(day !== 0) {
if (day !== 0) {
addDays(newDate, (-1) * day);
}
return newDate;


+ 14
- 15
src/js/utils/dom.js Näytä tiedosto

@@ -1,9 +1,8 @@
export function $(expr, con) {
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
return typeof expr === "string" ? (con || document).querySelector(expr) : expr || null;
}

export function findNodeIndex(node)
{
export function findNodeIndex(node) {
var i = 0;
while (node.previousSibling) {
node = node.previousSibling;
@@ -27,12 +26,12 @@ $.create = (tag, o) => {
element.appendChild(ref);

} else if (i === "styles") {
if(typeof val === "object") {
if (typeof val === "object") {
Object.keys(val).map(prop => {
element.style[prop] = val[prop];
});
}
} else if (i in element ) {
} else if (i in element) {
element[i] = val;
}
else {
@@ -67,9 +66,9 @@ export function isElementInViewport(el) {

return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}

@@ -81,7 +80,7 @@ export function getElementContentWidth(element) {
return element.clientWidth - padding;
}

export function bind(element, o){
export function bind(element, o) {
if (element) {
for (var event in o) {
var callback = o[event];
@@ -93,12 +92,12 @@ export function bind(element, o){
}
}

export function unbind(element, o){
export function unbind(element, o) {
if (element) {
for (var event in o) {
var callback = o[event];

event.split(/\s+/).forEach(function(event) {
event.split(/\s+/).forEach(function (event) {
element.removeEventListener(event, callback);
});
}
@@ -108,7 +107,7 @@ export function unbind(element, o){
export function fire(target, type, properties) {
var evt = document.createEvent("HTMLEvents");

evt.initEvent(type, true, true );
evt.initEvent(type, true, true);

for (var j in properties) {
evt[j] = properties[j];
@@ -119,17 +118,17 @@ export function fire(target, type, properties) {

// https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
export function forEachNode(nodeList, callback, scope) {
if(!nodeList) return;
if (!nodeList) return;
for (var i = 0; i < nodeList.length; i++) {
callback.call(scope, nodeList[i], i);
}
}

export function activate($parent, $child, commonClass, activeClass='active', index = -1) {
export function activate($parent, $child, commonClass, activeClass = 'active', index = -1) {
let $children = $parent.querySelectorAll(`.${commonClass}.${activeClass}`);

forEachNode($children, (node, i) => {
if(index >= 0 && i <= index) return;
if (index >= 0 && i <= index) return;
node.classList.remove(activeClass);
});



+ 10
- 10
src/js/utils/draw-utils.js Näytä tiedosto

@@ -17,7 +17,7 @@ export function equilizeNoOfElements(array1, array2,
extraCount = array2.length - array1.length) {

// Doesn't work if either has zero elements.
if(extraCount > 0) {
if (extraCount > 0) {
array1 = fillArray(array1, extraCount);
} else {
array2 = fillArray(array2, extraCount);
@@ -30,7 +30,7 @@ export function truncateString(txt, len) {
return;
}
if (txt.length > len) {
return txt.slice(0, len-3) + '...';
return txt.slice(0, len - 3) + '...';
} else {
return txt;
}
@@ -47,18 +47,18 @@ export function shortenLargeNumber(label) {
// Using absolute since log wont work for negative numbers
let p = Math.floor(Math.log10(Math.abs(number)));
if (p <= 2) return number; // Return as is for a 3 digit number of less
let l = Math.floor(p / 3);
let l = Math.floor(p / 3);
let shortened = (Math.pow(10, p - l * 3) * +(number / Math.pow(10, p)).toFixed(1));

// Correct for floating point error upto 2 decimal places
return Math.round(shortened*100)/100 + ' ' + ['', 'K', 'M', 'B', 'T'][l];
return Math.round(shortened * 100) / 100 + ' ' + ['', 'K', 'M', 'B', 'T'][l];
}

// cubic bezier curve calculation (from example by François Romain)
export function getSplineCurvePointsStr(xList, yList) {

let points=[];
for(let i=0;i<xList.length;i++){
let points = [];
for (let i = 0; i < xList.length; i++) {
points.push([xList[i], yList[i]]);
}

@@ -71,7 +71,7 @@ export function getSplineCurvePointsStr(xList, yList) {
angle: Math.atan2(lengthY, lengthX)
};
};
let controlPoint = (current, previous, next, reverse) => {
let p = previous || current;
let n = next || current;
@@ -82,18 +82,18 @@ export function getSplineCurvePointsStr(xList, yList) {
let y = current[1] + Math.sin(angle) * length;
return [x, y];
};
let bezierCommand = (point, i, a) => {
let cps = controlPoint(a[i - 1], a[i - 2], point);
let cpe = controlPoint(point, a[i - 1], a[i + 1], true);
return `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${point[0]},${point[1]}`;
};
let pointStr = (points, command) => {
return points.reduce((acc, point, i, a) => i === 0
? `${point[0]},${point[1]}`
: `${acc} ${command(point, i, a)}`, '');
};
return pointStr(points, bezierCommand);
}

+ 66
- 66
src/js/utils/draw.js Näytä tiedosto

@@ -10,7 +10,7 @@ const BASE_LINE_COLOR = '#E2E6E9';
const FONT_FILL = '#313B44';

function $(expr, con) {
return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
return typeof expr === "string" ? (con || document).querySelector(expr) : expr || null;
}

export function createSVG(tag, o) {
@@ -28,14 +28,14 @@ export function createSVG(tag, o) {
element.appendChild(ref);

} else if (i === "styles") {
if(typeof val === "object") {
if (typeof val === "object") {
Object.keys(val).map(prop => {
element.style[prop] = val[prop];
});
}
} else {
if(i === "className") { i = "class"; }
if(i === "innerHTML") {
if (i === "className") { i = "class"; }
if (i === "innerHTML") {
element['textContent'] = val;
} else {
element.setAttribute(i, val);
@@ -81,16 +81,16 @@ export function makeSVGDefs(svgContainer) {
});
}

export function makeSVGGroup(className, transform='', parent=undefined) {
export function makeSVGGroup(className, transform = '', parent = undefined) {
let args = {
className: className,
transform: transform
};
if(parent) args.inside = parent;
if (parent) args.inside = parent;
return createSVG('g', args);
}

export function wrapInSVGGroup(elements, className='') {
export function wrapInSVGGroup(elements, className = '') {
let g = createSVG('g', {
className: className
});
@@ -98,7 +98,7 @@ export function wrapInSVGGroup(elements, className='') {
return g;
}

export function makePath(pathStr, className='', stroke='none', fill='none', strokeWidth=2) {
export function makePath(pathStr, className = '', stroke = 'none', fill = 'none', strokeWidth = 2) {
return createSVG('path', {
className: className,
d: pathStr,
@@ -110,7 +110,7 @@ export function makePath(pathStr, className='', stroke='none', fill='none', stro
});
}

export function makeArcPathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
export function makeArcPathStr(startPosition, endPosition, center, radius, clockWise = 1, largeArc = 0) {
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y];
return `M${center.x} ${center.y}
@@ -119,7 +119,7 @@ export function makeArcPathStr(startPosition, endPosition, center, radius, clock
${arcEndX} ${arcEndY} z`;
}

export function makeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
export function makeCircleStr(startPosition, endPosition, center, radius, clockWise = 1, largeArc = 0) {
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, center.y * 2, center.y + endPosition.y];
return `M${center.x} ${center.y}
@@ -131,7 +131,7 @@ export function makeCircleStr(startPosition, endPosition, center, radius, clockW
${arcEndX} ${arcEndY} z`;
}

export function makeArcStrokePathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
export function makeArcStrokePathStr(startPosition, endPosition, center, radius, clockWise = 1, largeArc = 0) {
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y];

@@ -140,7 +140,7 @@ export function makeArcStrokePathStr(startPosition, endPosition, center, radius,
${arcEndX} ${arcEndY}`;
}

export function makeStrokeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
export function makeStrokeCircleStr(startPosition, endPosition, center, radius, clockWise = 1, largeArc = 0) {
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, radius * 2 + arcStartY, center.y + startPosition.y];

@@ -153,7 +153,7 @@ export function makeStrokeCircleStr(startPosition, endPosition, center, radius,
}

export function makeGradient(svgDefElem, color, lighter = false) {
let gradientId ='path-fill-gradient' + '-' + color + '-' +(lighter ? 'lighter' : 'default');
let gradientId = 'path-fill-gradient' + '-' + color + '-' + (lighter ? 'lighter' : 'default');
let gradientDef = renderVerticalGradient(svgDefElem, gradientId);
let opacities = [1, 0.6, 0.2];
if (lighter) {
@@ -169,20 +169,20 @@ export function makeGradient(svgDefElem, color, lighter = false) {

export function rightRoundedBar(x, width, height) {
// https://medium.com/@dennismphil/one-side-rounded-rectangle-using-svg-fb31cf318d90
let radius = height/2;
let radius = height / 2;
let xOffset = width - radius;

return `M${x},0 h${xOffset} q${radius},0 ${radius},${radius} q0,${radius} -${radius},${radius} h-${xOffset} v${height}z`;
}

export function leftRoundedBar(x, width, height) {
let radius = height/2;
let radius = height / 2;
let xOffset = width - radius;

return `M${x + radius},0 h${xOffset} v${height} h-${xOffset} q-${radius}, 0 -${radius},-${radius} q0,-${radius} ${radius},-${radius}z`;
}

export function percentageBar(x, y, width, height, isFirst, isLast, fill='none') {
export function percentageBar(x, y, width, height, isFirst, isLast, fill = 'none') {
if (isLast) {
let pathStr = rightRoundedBar(x, width, height);
return makePath(pathStr, 'percentage-bar', null, fill);
@@ -205,7 +205,7 @@ export function percentageBar(x, y, width, height, isFirst, isLast, fill='none')
return createSVG("rect", args);
}

export function heatSquare(className, x, y, size, radius, fill='none', data={}) {
export function heatSquare(className, x, y, size, radius, fill = 'none', data = {}) {
let args = {
className: className,
x: x,
@@ -294,7 +294,7 @@ export function makeText(className, x, y, content, options = {}) {
});
}

function makeVertLine(x, label, y1, y2, options={}) {
function makeVertLine(x, label, y1, y2, options = {}) {
let l = createSVG('line', {
className: 'line-vertical ' + options.className,
x1: 0,
@@ -316,7 +316,7 @@ function makeVertLine(x, label, y1, y2, options={}) {
});

let line = createSVG('g', {
transform: `translate(${ x }, 0)`
transform: `translate(${x}, 0)`
});

line.appendChild(l);
@@ -325,12 +325,12 @@ function makeVertLine(x, label, y1, y2, options={}) {
return line;
}

function makeHoriLine(y, label, x1, x2, options={}) {
if(!options.lineType) options.lineType = '';
function makeHoriLine(y, label, x1, x2, options = {}) {
if (!options.lineType) options.lineType = '';
if (options.shortenNumbers) label = shortenLargeNumber(label);

let className = 'line-horizontal ' + options.className +
(options.lineType === "dashed" ? "dashed": "");
(options.lineType === "dashed" ? "dashed" : "");

let l = createSVG('line', {
className: className,
@@ -349,7 +349,7 @@ function makeHoriLine(y, label, x1, x2, options={}) {
dy: (FONT_SIZE / 2 - 2) + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': x1 < x2 ? 'end' : 'start',
innerHTML: label+""
innerHTML: label + ""
});

let line = createSVG('g', {
@@ -357,7 +357,7 @@ function makeHoriLine(y, label, x1, x2, options={}) {
'stroke-opacity': 1
});

if(text === 0 || text === '0') {
if (text === 0 || text === '0') {
line.style.stroke = "rgba(27, 31, 35, 0.6)";
}

@@ -367,19 +367,19 @@ function makeHoriLine(y, label, x1, x2, options={}) {
return line;
}

export function yLine(y, label, width, options={}) {
export function yLine(y, label, width, options = {}) {
if (!isValidNumber(y)) y = 0;

if(!options.pos) options.pos = 'left';
if(!options.offset) options.offset = 0;
if(!options.mode) options.mode = 'span';
if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.className) options.className = '';
if (!options.pos) options.pos = 'left';
if (!options.offset) options.offset = 0;
if (!options.mode) options.mode = 'span';
if (!options.stroke) options.stroke = BASE_LINE_COLOR;
if (!options.className) options.className = '';

let x1 = -1 * AXIS_TICK_LENGTH;
let x2 = options.mode === 'span' ? width + AXIS_TICK_LENGTH : 0;

if(options.mode === 'tick' && options.pos === 'right') {
if (options.mode === 'tick' && options.pos === 'right') {
x1 = width + AXIS_TICK_LENGTH;
x2 = width;
}
@@ -398,13 +398,13 @@ export function yLine(y, label, width, options={}) {
});
}

export function xLine(x, label, height, options={}) {
export function xLine(x, label, height, options = {}) {
if (!isValidNumber(x)) x = 0;

if(!options.pos) options.pos = 'bottom';
if(!options.offset) options.offset = 0;
if(!options.mode) options.mode = 'span';
if(!options.className) options.className = '';
if (!options.pos) options.pos = 'bottom';
if (!options.offset) options.offset = 0;
if (!options.mode) options.mode = 'span';
if (!options.className) options.className = '';

// Draw X axis line in span/tick mode with optional label
// y2(span)
@@ -420,7 +420,7 @@ export function xLine(x, label, height, options={}) {
let y1 = height + AXIS_TICK_LENGTH;
let y2 = options.mode === 'span' ? -1 * AXIS_TICK_LENGTH : height;

if(options.mode === 'tick' && options.pos === 'top') {
if (options.mode === 'tick' && options.pos === 'top') {
// top axis ticks
y1 = -1 * AXIS_TICK_LENGTH;
y2 = 0;
@@ -432,8 +432,8 @@ export function xLine(x, label, height, options={}) {
});
}

export function yMarker(y, label, width, options={}) {
if(!options.labelPos) options.labelPos = 'right';
export function yMarker(y, label, width, options = {}) {
if (!options.labelPos) options.labelPos = 'right';
let x = options.labelPos === 'left' ? LABEL_MARGIN
: width - getStringWidth(label, 5) - LABEL_MARGIN;

@@ -444,7 +444,7 @@ export function yMarker(y, label, width, options={}) {
dy: (FONT_SIZE / -2) + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': 'start',
innerHTML: label+""
innerHTML: label + ""
});

let line = makeHoriLine(y, '', 0, width, {
@@ -458,7 +458,7 @@ export function yMarker(y, label, width, options={}) {
return line;
}

export function yRegion(y1, y2, width, label, options={}) {
export function yRegion(y1, y2, width, label, options = {}) {
// return a group
let height = y1 - y2;

@@ -476,9 +476,9 @@ export function yRegion(y1, y2, width, label, options={}) {
height: height
});

if(!options.labelPos) options.labelPos = 'right';
if (!options.labelPos) options.labelPos = 'right';
let x = options.labelPos === 'left' ? LABEL_MARGIN
: width - getStringWidth(label+"", 4.5) - LABEL_MARGIN;
: width - getStringWidth(label + "", 4.5) - LABEL_MARGIN;

let labelSvg = createSVG('text', {
className: 'chart-label',
@@ -487,7 +487,7 @@ export function yRegion(y1, y2, width, label, options={}) {
dy: (FONT_SIZE / -2) + 'px',
'font-size': FONT_SIZE + 'px',
'text-anchor': 'start',
innerHTML: label+""
innerHTML: label + ""
});

let region = createSVG('g', {
@@ -500,11 +500,11 @@ export function yRegion(y1, y2, width, label, options={}) {
return region;
}

export function datasetBar(x, yTop, width, color, label='', index=0, offset=0, meta={}) {
export function datasetBar(x, yTop, width, color, label = '', index = 0, offset = 0, meta = {}) {
let [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine);
y -= offset;

if(height === 0) {
if (height === 0) {
height = meta.minHeight;
y -= meta.minHeight;
}
@@ -547,14 +547,14 @@ export function datasetBar(x, yTop, width, color, label='', index=0, offset=0, m

label += "";

if(!label && !label.length) {
if (!label && !label.length) {
return rect;
} else {
rect.setAttribute('y', 0);
rect.setAttribute('x', 0);
let text = createSVG('text', {
className: 'data-point-value',
x: width/2,
x: width / 2,
y: 0,
dy: (FONT_SIZE / 2 * -1) + 'px',
'font-size': FONT_SIZE + 'px',
@@ -573,7 +573,7 @@ export function datasetBar(x, yTop, width, color, label='', index=0, offset=0, m
}
}

export function datasetDot(x, y, radius, color, label='', index=0) {
export function datasetDot(x, y, radius, color, label = '', index = 0) {
let dot = createSVG('circle', {
style: `fill: ${color}`,
'data-point-index': index,
@@ -584,7 +584,7 @@ export function datasetDot(x, y, radius, color, label='', index=0) {

label += "";

if(!label && !label.length) {
if (!label && !label.length) {
return dot;
} else {
dot.setAttribute('cy', 0);
@@ -611,7 +611,7 @@ export function datasetDot(x, y, radius, color, label='', index=0) {
}
}

export function getPaths(xList, yList, color, options={}, meta={}) {
export function getPaths(xList, yList, color, options = {}, meta = {}) {
let pointsList = yList.map((y, i) => (xList[i] + ',' + y));
let pointsStr = pointsList.join("L");

@@ -619,10 +619,10 @@ export function getPaths(xList, yList, color, options={}, meta={}) {
if (options.spline)
pointsStr = getSplineCurvePointsStr(xList, yList);

let path = makePath("M"+pointsStr, 'line-graph-path', color);
let path = makePath("M" + pointsStr, 'line-graph-path', color);

// HeatLine
if(options.heatline) {
if (options.heatline) {
let gradient_id = makeGradient(meta.svgDefs, color);
path.style.stroke = `url(#${gradient_id})`;
}
@@ -632,7 +632,7 @@ export function getPaths(xList, yList, color, options={}, meta={}) {
};

// Region
if(options.regionFill) {
if (options.regionFill) {
let gradient_id_region = makeGradient(meta.svgDefs, color, true);

let pathStr = "M" + `${xList[0]},${meta.zeroLine}L` + pointsStr + `L${xList.slice(-1)[0]},${meta.zeroLine}`;
@@ -645,7 +645,7 @@ export function getPaths(xList, yList, color, options={}, meta={}) {
export let makeOverlay = {
'bar': (unit) => {
let transformValue;
if(unit.nodeName !== 'rect') {
if (unit.nodeName !== 'rect') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
@@ -653,7 +653,7 @@ export let makeOverlay = {
overlay.style.fill = '#000000';
overlay.style.opacity = '0.4';

if(transformValue) {
if (transformValue) {
overlay.setAttribute('transform', transformValue);
}
return overlay;
@@ -661,7 +661,7 @@ export let makeOverlay = {

'dot': (unit) => {
let transformValue;
if(unit.nodeName !== 'circle') {
if (unit.nodeName !== 'circle') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
@@ -672,7 +672,7 @@ export let makeOverlay = {
overlay.setAttribute('fill', fill);
overlay.style.opacity = '0.6';

if(transformValue) {
if (transformValue) {
overlay.setAttribute('transform', transformValue);
}
return overlay;
@@ -680,7 +680,7 @@ export let makeOverlay = {

'heat_square': (unit) => {
let transformValue;
if(unit.nodeName !== 'circle') {
if (unit.nodeName !== 'circle') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
@@ -691,7 +691,7 @@ export let makeOverlay = {
overlay.setAttribute('fill', fill);
overlay.style.opacity = '0.6';

if(transformValue) {
if (transformValue) {
overlay.setAttribute('transform', transformValue);
}
return overlay;
@@ -701,7 +701,7 @@ export let makeOverlay = {
export let updateOverlay = {
'bar': (unit, overlay) => {
let transformValue;
if(unit.nodeName !== 'rect') {
if (unit.nodeName !== 'rect') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
@@ -712,14 +712,14 @@ export let updateOverlay = {
overlay.setAttribute(attr.name, attr.nodeValue);
});

if(transformValue) {
if (transformValue) {
overlay.setAttribute('transform', transformValue);
}
},

'dot': (unit, overlay) => {
let transformValue;
if(unit.nodeName !== 'circle') {
if (unit.nodeName !== 'circle') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
@@ -730,14 +730,14 @@ export let updateOverlay = {
overlay.setAttribute(attr.name, attr.nodeValue);
});

if(transformValue) {
if (transformValue) {
overlay.setAttribute('transform', transformValue);
}
},

'heat_square': (unit, overlay) => {
let transformValue;
if(unit.nodeName !== 'circle') {
if (unit.nodeName !== 'circle') {
transformValue = unit.getAttribute('transform');
unit = unit.childNodes[0];
}
@@ -748,7 +748,7 @@ export let updateOverlay = {
overlay.setAttribute(attr.name, attr.nodeValue);
});

if(transformValue) {
if (transformValue) {
overlay.setAttribute('transform', transformValue);
}
},


+ 2
- 2
src/js/utils/export.js Näytä tiedosto

@@ -4,13 +4,13 @@ import { CSSTEXT } from '../../css/chartsCss';
export function downloadFile(filename, data) {
var a = document.createElement('a');
a.style = "display: none";
var blob = new Blob(data, {type: "image/svg+xml; charset=utf-8"});
var blob = new Blob(data, { type: "image/svg+xml; charset=utf-8" });
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function(){
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 300);


+ 7
- 7
src/js/utils/helpers.js Näytä tiedosto

@@ -14,10 +14,10 @@ export function floatTwo(d) {
* @param {Array} arr2 Second array
*/
export function arraysEqual(arr1, arr2) {
if(arr1.length !== arr2.length) return false;
if (arr1.length !== arr2.length) return false;
let areEqual = true;
arr1.map((d, i) => {
if(arr2[i] !== d) areEqual = false;
if (arr2[i] !== d) areEqual = false;
});
return areEqual;
}
@@ -46,8 +46,8 @@ export function shuffle(array) {
* @param {Object} element element to fill with
* @param {Boolean} start fill at start?
*/
export function fillArray(array, count, element, start=false) {
if(!element) {
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);
@@ -61,16 +61,16 @@ export function fillArray(array, count, element, start=false) {
* @param {Number} charWidth Width of single char in pixels
*/
export function getStringWidth(string, charWidth) {
return (string+"").length * charWidth;
return (string + "").length * charWidth;
}

export function bindChange(obj, getFn, setFn) {
return new Proxy(obj, {
set: function(target, prop, value) {
set: function (target, prop, value) {
setFn();
return Reflect.set(target, prop, value);
},
get: function(target, prop) {
get: function (target, prop) {
getFn();
return Reflect.get(target, prop);
}


+ 30
- 30
src/js/utils/intervals.js Näytä tiedosto

@@ -5,25 +5,25 @@ function normalize(x) {
// Returns normalized number and exponent
// https://stackoverflow.com/q/9383593/6495043

if(x===0) {
if (x === 0) {
return [0, 0];
}
if(isNaN(x)) {
return {mantissa: -6755399441055744, exponent: 972};
if (isNaN(x)) {
return { mantissa: -6755399441055744, exponent: 972 };
}
var sig = x > 0 ? 1 : -1;
if(!isFinite(x)) {
return {mantissa: sig * 4503599627370496, exponent: 972};
if (!isFinite(x)) {
return { mantissa: sig * 4503599627370496, exponent: 972 };
}

x = Math.abs(x);
var exp = Math.floor(Math.log10(x));
var man = x/Math.pow(10, exp);
var man = x / Math.pow(10, exp);

return [sig * man, exp];
}

function getChartRangeIntervals(max, min=0) {
function getChartRangeIntervals(max, min = 0) {
let upperBound = Math.ceil(max);
let lowerBound = Math.floor(min);
let range = upperBound - lowerBound;
@@ -32,38 +32,38 @@ function getChartRangeIntervals(max, min=0) {
let partSize = 1;

// To avoid too many partitions
if(range > 5) {
if(range % 2 !== 0) {
if (range > 5) {
if (range % 2 !== 0) {
upperBound++;
// Recalc range
range = upperBound - lowerBound;
}
noOfParts = range/2;
noOfParts = range / 2;
partSize = 2;
}

// Special case: 1 and 2
if(range <= 2) {
if (range <= 2) {
noOfParts = 4;
partSize = range/noOfParts;
partSize = range / noOfParts;
}

// Special case: 0
if(range === 0) {
if (range === 0) {
noOfParts = 5;
partSize = 1;
}

let intervals = [];
for(var i = 0; i <= noOfParts; i++){
for (var i = 0; i <= noOfParts; i++) {
intervals.push(lowerBound + partSize * i);
}
return intervals;
}

function getChartIntervals(maxValue, minValue=0) {
function getChartIntervals(maxValue, minValue = 0) {
let [normalMaxValue, exponent] = normalize(maxValue);
let normalMinValue = minValue ? minValue/Math.pow(10, exponent): 0;
let normalMinValue = minValue ? minValue / Math.pow(10, exponent) : 0;

// Allow only 7 significant digits
normalMaxValue = normalMaxValue.toFixed(6);
@@ -73,7 +73,7 @@ function getChartIntervals(maxValue, minValue=0) {
return intervals;
}

export function calcChartIntervals(values, withMinimum=false) {
export function calcChartIntervals(values, withMinimum = false) {
//*** Where the magic happens ***

// Calculates best-fit y intervals from given values
@@ -92,7 +92,7 @@ export function calcChartIntervals(values, withMinimum=false) {

// Then unshift the negative values
let value = 0;
for(var i = 1; value < absMinValue; i++) {
for (var i = 1; value < absMinValue; i++) {
value += intervalSize;
intervals.unshift((-1) * value);
}
@@ -101,9 +101,9 @@ export function calcChartIntervals(values, withMinimum=false) {

// CASE I: Both non-negative

if(maxValue >= 0 && minValue >= 0) {
if (maxValue >= 0 && minValue >= 0) {
exponent = normalize(maxValue)[1];
if(!withMinimum) {
if (!withMinimum) {
intervals = getChartIntervals(maxValue);
} else {
intervals = getChartIntervals(maxValue, minValue);
@@ -112,7 +112,7 @@ export function calcChartIntervals(values, withMinimum=false) {

// CASE II: Only minValue negative

else if(maxValue > 0 && minValue < 0) {
else if (maxValue > 0 && minValue < 0) {
// `withMinimum` irrelevant in this case,
// We'll be handling both sides of zero separately
// (both starting from zero)
@@ -121,7 +121,7 @@ export function calcChartIntervals(values, withMinimum=false) {

let absMinValue = Math.abs(minValue);

if(maxValue >= absMinValue) {
if (maxValue >= absMinValue) {
exponent = normalize(maxValue)[1];
intervals = getPositiveFirstIntervals(maxValue, absMinValue);
} else {
@@ -135,7 +135,7 @@ export function calcChartIntervals(values, withMinimum=false) {

// CASE III: Both non-positive

else if(maxValue <= 0 && minValue <= 0) {
else if (maxValue <= 0 && minValue <= 0) {
// Mirrored Case I:
// Work with positives, then reverse the sign and array

@@ -143,7 +143,7 @@ export function calcChartIntervals(values, withMinimum=false) {
let pseudoMinValue = Math.abs(maxValue);

exponent = normalize(pseudoMaxValue)[1];
if(!withMinimum) {
if (!withMinimum) {
intervals = getChartIntervals(pseudoMaxValue);
} else {
intervals = getChartIntervals(pseudoMaxValue, pseudoMinValue);
@@ -158,11 +158,11 @@ export function calcChartIntervals(values, withMinimum=false) {
export function getZeroIndex(yPts) {
let zeroIndex;
let interval = getIntervalSize(yPts);
if(yPts.indexOf(0) >= 0) {
if (yPts.indexOf(0) >= 0) {
// the range has a given zero
// zero-line on the chart
zeroIndex = yPts.indexOf(0);
} else if(yPts[0] > 0) {
} else if (yPts[0] > 0) {
// Minimum value is positive
// zero-line is off the chart: below
let min = yPts[0];
@@ -181,7 +181,7 @@ export function getRealIntervals(max, noOfIntervals, min = 0, asc = 1) {
let part = range * 1.0 / noOfIntervals;
let intervals = [];

for(var i = 0; i <= noOfIntervals; i++) {
for (var i = 0; i <= noOfIntervals; i++) {
intervals.push(min + part * i);
}

@@ -193,7 +193,7 @@ export function getIntervalSize(orderedArray) {
}

export function getValueRange(orderedArray) {
return orderedArray[orderedArray.length-1] - orderedArray[0];
return orderedArray[orderedArray.length - 1] - orderedArray[0];
}

export function scale(val, yAxis) {
@@ -210,7 +210,7 @@ export function isInRange2D(coord, minCoord, maxCoord) {
}

export function getClosestInArray(goal, arr, index = false) {
let closest = arr.reduce(function(prev, curr) {
let closest = arr.reduce(function (prev, curr) {
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
}, []);

@@ -226,7 +226,7 @@ export function calcDistribution(values, distributionSize) {
let distributionStep = 1 / (distributionSize - 1);
let distribution = [];

for(var i = 0; i < distributionSize; i++) {
for (var i = 0; i < distributionSize; i++) {
let checkpoint = dataMaxValue * (distributionStep * i);
distribution.push(checkpoint);
}


Ladataan…
Peruuta
Tallenna