frappe-charts
Advanced tools
Comparing version 1.5.5 to 2.0.0-rc1
{ | ||
"name": "frappe-charts", | ||
"version": "1.5.5", | ||
"version": "2.0.0-rc1", | ||
"main": "src/js/chart.js", | ||
"module": "dist/frappe-charts.esm.js", | ||
"browser": "dist/frappe-charts.umd.js", | ||
"common": "dist/frappe-charts.cjs.js", | ||
"unnpkg": "dist/frappe-charts.umd.js", | ||
"type": "module", | ||
"description": "https://frappe.github.io/charts", | ||
"main": "dist/frappe-charts.min.cjs.js", | ||
"module": "dist/frappe-charts.min.esm.js", | ||
"src": "dist/frappe-charts.esm.js", | ||
"browser": "dist/frappe-charts.min.iife.js", | ||
"directories": { | ||
@@ -37,33 +39,13 @@ "doc": "docs" | ||
"devDependencies": { | ||
"autoprefixer": "^8.2.0", | ||
"babel-core": "^6.26.3", | ||
"babel-plugin-external-helpers": "^6.22.0", | ||
"babel-plugin-istanbul": "^5.1.4", | ||
"babel-preset-env": "^1.7.0", | ||
"babel-preset-latest": "^6.24.1", | ||
"babel-register": "^6.26.0", | ||
"clean-css": "^4.1.11", | ||
"coveralls": "^3.0.0", | ||
"cross-env": "^5.1.4", | ||
"cssnano": "^4.1.10", | ||
"eslint": "^4.18.2", | ||
"mocha": "^5.0.5", | ||
"node-sass": "^4.12.0", | ||
"npm-run-all": "^4.1.1", | ||
"nyc": "^14.1.1", | ||
"postcss": "^6.0.21", | ||
"postcss-cssnext": "^3.0.2", | ||
"postcss-nested": "^2.1.2", | ||
"precss": "^3.1.2", | ||
"rollup": "^0.50.0", | ||
"rollup-plugin-babel": "^3.0.2", | ||
"rollup-plugin-eslint": "^6.0.0", | ||
"rollup-plugin-node-resolve": "^3.0.0", | ||
"rollup-plugin-postcss": "^2.0.3", | ||
"rollup-plugin-replace": "^2.0.0", | ||
"rollup-plugin-uglify": "^2.0.1", | ||
"rollup-plugin-uglify-es": "0.0.1", | ||
"rollup-watch": "^4.3.1" | ||
}, | ||
"dependencies": {} | ||
"@babel/core": "^7.10.5", | ||
"@babel/preset-env": "^7.10.4", | ||
"rollup": "^2.21.0", | ||
"rollup-plugin-babel": "^4.4.0", | ||
"rollup-plugin-bundle-size": "^1.0.3", | ||
"rollup-plugin-commonjs": "^10.1.0", | ||
"rollup-plugin-eslint": "^7.0.0", | ||
"rollup-plugin-postcss": "^3.1.3", | ||
"rollup-plugin-scss": "^2.5.0", | ||
"rollup-plugin-terser": "^6.1.0" | ||
} | ||
} |
@@ -1,1 +0,1 @@ | ||
export const CSSTEXT = ".chart-container{position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Roboto','Oxygen','Ubuntu','Cantarell','Fira Sans','Droid Sans','Helvetica Neue',sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.chart-container .legend-dataset-text{fill:#6c7680;font-weight:600}.graph-svg-tip{position:absolute;z-index:99999;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.graph-svg-tip ul{padding-left:0;display:flex}.graph-svg-tip ol{padding-left:0;display:flex}.graph-svg-tip ul.data-point-list li{min-width:90px;flex:1;font-weight:600}.graph-svg-tip strong{color:#dfe2e5;font-weight:600}.graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:' ';border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}"; | ||
export const CSSTEXT = ".chart-container{position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Roboto','Oxygen','Ubuntu','Cantarell','Fira Sans','Droid Sans','Helvetica Neue',sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.chart-container .legend-dataset-text{fill:#6c7680;font-weight:600}.graph-svg-tip{position:absolute;z-index:99999;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.graph-svg-tip ul{padding-left:0;display:flex}.graph-svg-tip ol{padding-left:0;display:flex}.graph-svg-tip ul.data-point-list li{min-width:90px;flex:1;font-weight:600}.graph-svg-tip strong{color:#dfe2e5;font-weight:600}.graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:' ';border:5px solid transparent;}.graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}"; |
import '../css/charts.scss'; | ||
// import MultiAxisChart from './charts/MultiAxisChart'; | ||
import PercentageChart from './charts/PercentageChart'; | ||
@@ -13,3 +12,2 @@ import PieChart from './charts/PieChart'; | ||
line: AxisChart, | ||
// multiaxis: MultiAxisChart, | ||
percentage: PercentageChart, | ||
@@ -16,0 +14,0 @@ heatmap: Heatmap, |
import BaseChart from './BaseChart'; | ||
import { truncateString } from '../utils/draw-utils'; | ||
import { legendDot } from '../utils/draw'; | ||
import { round } from '../utils/helpers'; | ||
import { getExtraWidth } from '../utils/constants'; | ||
@@ -18,2 +15,3 @@ export default class AggregationChart extends BaseChart { | ||
this.config.maxLegendPoints = args.maxLegendPoints || 20; | ||
this.config.legendRowHeight = 60; | ||
} | ||
@@ -35,13 +33,13 @@ | ||
let totals = allTotals; | ||
if(allTotals.length > maxSlices) { | ||
if (allTotals.length > maxSlices) { | ||
// Prune and keep a grey area for rest as per maxSlices | ||
allTotals.sort((a, b) => { return b[0] - a[0]; }); | ||
totals = allTotals.slice(0, maxSlices-1); | ||
let remaining = allTotals.slice(maxSlices-1); | ||
totals = allTotals.slice(0, maxSlices - 1); | ||
let remaining = allTotals.slice(maxSlices - 1); | ||
let sumOfRemaining = 0; | ||
remaining.map(d => {sumOfRemaining += d[0];}); | ||
remaining.map(d => { sumOfRemaining += d[0]; }); | ||
totals.push([sumOfRemaining, 'Rest']); | ||
this.colors[maxSlices-1] = 'grey'; | ||
this.colors[maxSlices - 1] = 'grey'; | ||
} | ||
@@ -67,32 +65,20 @@ | ||
this.legendTotals = s.sliceTotals.slice(0, this.config.maxLegendPoints); | ||
super.renderLegend(this.legendTotals); | ||
} | ||
let count = 0; | ||
let y = 0; | ||
this.legendTotals.map((d, i) => { | ||
let barWidth = 150; | ||
let divisor = Math.floor( | ||
(this.width - getExtraWidth(this.measures))/barWidth | ||
); | ||
if (this.legendTotals.length < divisor) { | ||
barWidth = this.width/this.legendTotals.length; | ||
} | ||
if(count > divisor) { | ||
count = 0; | ||
y += 20; | ||
} | ||
let x = barWidth * count + 5; | ||
let label = this.config.truncateLegends ? truncateString(s.labels[i], barWidth/10) : s.labels[i]; | ||
let formatted = this.config.formatTooltipY ? this.config.formatTooltipY(d) : d; | ||
let dot = legendDot( | ||
x, | ||
y, | ||
5, | ||
this.colors[i], | ||
`${label}: ${formatted}`, | ||
false | ||
); | ||
this.legendArea.appendChild(dot); | ||
count++; | ||
}); | ||
makeLegend(data, index, x_pos, y_pos) { | ||
let formatted = this.config.formatTooltipY ? this.config.formatTooltipY(data) : data; | ||
return legendDot( | ||
x_pos, | ||
y_pos, | ||
12, // size | ||
3, // dot radius | ||
this.colors[index], // fill | ||
this.state.labels[index], // label | ||
formatted, // value | ||
null, // base_font_size | ||
this.config.truncateLegends // truncate_legends | ||
); | ||
} | ||
} |
import BaseChart from './BaseChart'; | ||
import { dataPrep, zeroDataPrep, getShortenedLabels } from '../utils/axis-chart-utils'; | ||
import { AXIS_LEGEND_BAR_SIZE } from '../utils/constants'; | ||
import { getComponent } from '../objects/ChartComponents'; | ||
@@ -8,5 +7,7 @@ import { getOffset, fire } from '../utils/dom'; | ||
import { floatTwo } from '../utils/helpers'; | ||
import { makeOverlay, updateOverlay, legendBar } from '../utils/draw'; | ||
import { getTopOffset, getLeftOffset, MIN_BAR_PERCENT_HEIGHT, BAR_CHART_SPACE_RATIO, | ||
LINE_CHART_DOT_SIZE } from '../utils/constants'; | ||
import { makeOverlay, updateOverlay, legendDot } from '../utils/draw'; | ||
import { | ||
getTopOffset, getLeftOffset, MIN_BAR_PERCENT_HEIGHT, BAR_CHART_SPACE_RATIO, | ||
LINE_CHART_DOT_SIZE | ||
} from '../utils/constants'; | ||
@@ -27,3 +28,3 @@ export default class AxisChart extends BaseChart { | ||
setMeasures() { | ||
if(this.data.datasets.length <= 1) { | ||
if (this.data.datasets.length <= 1) { | ||
this.config.showLegend = 0; | ||
@@ -49,9 +50,10 @@ this.measures.paddings.bottom = 30; | ||
this.config.valuesOverPoints = options.valuesOverPoints; | ||
this.config.legendRowHeight = 30; | ||
} | ||
prepareData(data=this.data) { | ||
prepareData(data = this.data) { | ||
return dataPrep(data, this.type); | ||
} | ||
prepareFirstData(data=this.data) { | ||
prepareFirstData(data = this.data) { | ||
return zeroDataPrep(data); | ||
@@ -62,3 +64,3 @@ } | ||
this.calcXPositions(); | ||
if(!onlyWidthChange) { | ||
if (!onlyWidthChange) { | ||
this.calcYAxisParameters(this.getAllYValues(), this.type === 'line'); | ||
@@ -74,5 +76,5 @@ } | ||
s.unitWidth = this.width/(s.datasetLength); | ||
s.unitWidth = this.width / (s.datasetLength); | ||
// Default, as per bar, and mixed. Only line will be a special case | ||
s.xOffset = s.unitWidth/2; | ||
s.xOffset = s.unitWidth / 2; | ||
@@ -133,3 +135,3 @@ // // For a pure Line Chart | ||
let s = this.state; | ||
if(this.barOptions.stacked) { | ||
if (this.barOptions.stacked) { | ||
s.yExtremes = s.datasets[s.datasets.length - 1].cumulativeYPos; | ||
@@ -141,3 +143,3 @@ return; | ||
d.yPositions.map((pos, j) => { | ||
if(pos < s.yExtremes[j]) { | ||
if (pos < s.yExtremes[j]) { | ||
s.yExtremes[j] = pos; | ||
@@ -151,6 +153,6 @@ } | ||
let s = this.state; | ||
if(this.data.yMarkers) { | ||
if (this.data.yMarkers) { | ||
this.state.yMarkers = this.data.yMarkers.map(d => { | ||
d.position = scale(d.value, s.yAxis); | ||
if(!d.options) d.options = {}; | ||
if (!d.options) d.options = {}; | ||
// if(!d.label.includes(':')) { | ||
@@ -162,7 +164,7 @@ // d.label += ': ' + d.value; | ||
} | ||
if(this.data.yRegions) { | ||
if (this.data.yRegions) { | ||
this.state.yRegions = this.data.yRegions.map(d => { | ||
d.startPos = scale(d.start, s.yAxis); | ||
d.endPos = scale(d.end, s.yAxis); | ||
if(!d.options) d.options = {}; | ||
if (!d.options) d.options = {}; | ||
return d; | ||
@@ -176,3 +178,3 @@ }); | ||
if(this.barOptions.stacked) { | ||
if (this.barOptions.stacked) { | ||
key = 'cumulativeYs'; | ||
@@ -187,6 +189,6 @@ let cumulative = new Array(this.state.datasetLength).fill(0); | ||
let allValueLists = this.data.datasets.map(d => d[key]); | ||
if(this.data.yMarkers) { | ||
if (this.data.yMarkers) { | ||
allValueLists.push(this.data.yMarkers.map(d => d.value)); | ||
} | ||
if(this.data.yRegions) { | ||
if (this.data.yRegions) { | ||
this.data.yRegions.map(d => { | ||
@@ -210,3 +212,3 @@ allValueLists.push([d.end, d.start]); | ||
}, | ||
function() { | ||
function () { | ||
return this.state.yAxis; | ||
@@ -223,3 +225,3 @@ }.bind(this) | ||
}, | ||
function() { | ||
function () { | ||
let s = this.state; | ||
@@ -239,3 +241,3 @@ s.xAxis.calcLabels = getShortenedLabels(this.width, | ||
}, | ||
function() { | ||
function () { | ||
return this.state.yRegions; | ||
@@ -262,3 +264,3 @@ }.bind(this) | ||
}, | ||
function() { | ||
function () { | ||
let s = this.state; | ||
@@ -270,6 +272,6 @@ let d = s.datasets[index]; | ||
let barsWidth = s.unitWidth * (1 - spaceRatio); | ||
let barWidth = barsWidth/(stacked ? 1 : barDatasets.length); | ||
let barWidth = barsWidth / (stacked ? 1 : barDatasets.length); | ||
let xPositions = s.xAxis.positions.map(x => x - barsWidth/2); | ||
if(!stacked) { | ||
let xPositions = s.xAxis.positions.map(x => x - barsWidth / 2); | ||
if (!stacked) { | ||
xPositions = xPositions.map(p => p + barWidth * index); | ||
@@ -279,4 +281,4 @@ } | ||
let labels = new Array(s.datasetLength).fill(''); | ||
if(this.config.valuesOverPoints) { | ||
if(stacked && d.index === s.datasets.length - 1) { | ||
if (this.config.valuesOverPoints) { | ||
if (stacked && d.index === s.datasets.length - 1) { | ||
labels = d.cumulativeYs; | ||
@@ -289,3 +291,3 @@ } else { | ||
let offsets = new Array(s.datasetLength).fill(0); | ||
if(stacked) { | ||
if (stacked) { | ||
offsets = d.yPositions.map((y, j) => y - d.cumulativeYPos[j]); | ||
@@ -320,3 +322,3 @@ } | ||
spline: this.lineOptions.spline, | ||
hideDots: this.lineOptions.hideDots, | ||
showDots: this.lineOptions.showDots, | ||
hideLine: this.lineOptions.hideLine, | ||
@@ -327,3 +329,3 @@ | ||
}, | ||
function() { | ||
function () { | ||
let s = this.state; | ||
@@ -354,3 +356,3 @@ let d = s.datasets[index]; | ||
}, | ||
function() { | ||
function () { | ||
return this.state.yMarkers; | ||
@@ -370,3 +372,3 @@ }.bind(this) | ||
let component = getComponent(...args); | ||
if(args[0].includes('lineGraph') || args[0].includes('barGraph')) { | ||
if (args[0].includes('lineGraph') || args[0].includes('barGraph')) { | ||
this.dataUnitComponents.push(component); | ||
@@ -416,4 +418,4 @@ } | ||
if(relY < this.height + getTopOffset(m) | ||
&& relY > getTopOffset(m)) { | ||
if (relY < this.height + getTopOffset(m) | ||
&& relY > getTopOffset(m)) { | ||
this.mapTooltipXPosition(relX); | ||
@@ -428,3 +430,3 @@ } else { | ||
let s = this.state; | ||
if(!s.yExtremes) return; | ||
if (!s.yExtremes) return; | ||
@@ -438,3 +440,3 @@ let index = getClosestInArray(relX, s.xAxis.positions, true); | ||
dbi.yExtreme + this.tip.offset.y, | ||
{name: dbi.formattedLabel, value: ''}, | ||
{ name: dbi.formattedLabel, value: '' }, | ||
dbi.values, | ||
@@ -450,30 +452,28 @@ index | ||
let s = this.data; | ||
if(s.datasets.length > 1) { | ||
this.legendArea.textContent = ''; | ||
s.datasets.map((d, i) => { | ||
let barWidth = AXIS_LEGEND_BAR_SIZE; | ||
// let rightEndPoint = this.baseWidth - this.measures.margins.left - this.measures.margins.right; | ||
// let multiplier = s.datasets.length - i; | ||
let rect = legendBar( | ||
// rightEndPoint - multiplier * barWidth, // To right align | ||
barWidth * i, | ||
'0', | ||
barWidth, | ||
this.colors[i], | ||
d.name, | ||
this.config.truncateLegends); | ||
this.legendArea.appendChild(rect); | ||
}); | ||
if (s.datasets.length > 1) { | ||
super.renderLegend(s.datasets); | ||
} | ||
} | ||
makeLegend(data, index, x_pos, y_pos) { | ||
return legendDot( | ||
x_pos, | ||
y_pos + 5, // Extra offset | ||
12, // size | ||
3, // dot radius | ||
this.colors[index], // fill | ||
data.name, //label | ||
null, // value | ||
8.75, // base_font_size | ||
this.config.truncateLegends // truncate legends | ||
); | ||
} | ||
// Overlay | ||
makeOverlay() { | ||
if(this.init) { | ||
if (this.init) { | ||
this.init = 0; | ||
return; | ||
} | ||
if(this.overlayGuides) { | ||
if (this.overlayGuides) { | ||
this.overlayGuides.forEach(g => { | ||
@@ -493,3 +493,3 @@ let o = g.overlay; | ||
if(this.state.currentIndex === undefined) { | ||
if (this.state.currentIndex === undefined) { | ||
this.state.currentIndex = this.state.datasetLength - 1; | ||
@@ -508,3 +508,3 @@ } | ||
updateOverlayGuides() { | ||
if(this.overlayGuides) { | ||
if (this.overlayGuides) { | ||
this.overlayGuides.forEach(g => { | ||
@@ -555,3 +555,3 @@ let o = g.overlay; | ||
getDataPoint(index=this.state.currentIndex) { | ||
getDataPoint(index = this.state.currentIndex) { | ||
let s = this.state; | ||
@@ -569,5 +569,5 @@ let data_point = { | ||
index = parseInt(index); | ||
if(index < 0) index = 0; | ||
if(index >= s.xAxis.labels.length) index = s.xAxis.labels.length - 1; | ||
if(index === s.currentIndex) return; | ||
if (index < 0) index = 0; | ||
if (index >= s.xAxis.labels.length) index = s.xAxis.labels.length - 1; | ||
if (index === s.currentIndex) return; | ||
s.currentIndex = index; | ||
@@ -580,3 +580,3 @@ fire(this.parent, "data-select", this.getDataPoint()); | ||
// API | ||
addDataPoint(label, datasetValues, index=this.state.datasetLength) { | ||
addDataPoint(label, datasetValues, index = this.state.datasetLength) { | ||
super.addDataPoint(label, datasetValues, index); | ||
@@ -590,3 +590,3 @@ this.data.labels.splice(index, 0, label); | ||
removeDataPoint(index = this.state.datasetLength-1) { | ||
removeDataPoint(index = this.state.datasetLength - 1) { | ||
if (this.data.labels.length <= 1) { | ||
@@ -603,3 +603,3 @@ return; | ||
updateDataset(datasetValues, index=0) { | ||
updateDataset(datasetValues, index = 0) { | ||
this.data.datasets[index].values = datasetValues; | ||
@@ -613,3 +613,3 @@ this.update(this.data); | ||
this.data.datasets.map((d, i) => { | ||
if(datasets[i]) { | ||
if (datasets[i]) { | ||
d.values = datasets[i]; | ||
@@ -616,0 +616,0 @@ } |
import SvgTip from '../objects/SvgTip'; | ||
import { $, isElementInViewport, getElementContentWidth, isHidden } from '../utils/dom'; | ||
import { 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 { LEGEND_ITEM_WIDTH } from '../utils/constants'; | ||
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'; | ||
@@ -42,4 +45,4 @@ import { runSMILAnimation } from '../utils/animation'; | ||
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; | ||
@@ -52,3 +55,3 @@ | ||
if(this.config.isNavigable) { | ||
if (this.config.isNavigable) { | ||
this.overlays = []; | ||
@@ -73,3 +76,3 @@ } | ||
const color = getColor(string); | ||
if(!isValidColor(color)) { | ||
if (!isValidColor(color)) { | ||
console.warn('"' + string + '" is not a valid color.'); | ||
@@ -122,3 +125,3 @@ } else { | ||
if(this.independentWidth) { | ||
if (this.independentWidth) { | ||
args.styles = { width: this.independentWidth + 'px' }; | ||
@@ -138,5 +141,5 @@ } | ||
bindTooltip() {} | ||
bindTooltip() { } | ||
draw(onlyWidthChange=false, init=false) { | ||
draw(onlyWidthChange = false, init = false) { | ||
if (onlyWidthChange && isHidden(this.parent)) { | ||
@@ -156,5 +159,5 @@ // Don't update anything if the chart is hidden | ||
if(init) { | ||
if (init) { | ||
this.data = this.realData; | ||
setTimeout(() => {this.update(this.data);}, this.initTimeout); | ||
setTimeout(() => { this.update(this.data); }, this.initTimeout); | ||
} | ||
@@ -167,3 +170,3 @@ | ||
calc() {} // builds state | ||
calc() { } // builds state | ||
@@ -176,3 +179,3 @@ updateWidth() { | ||
makeChartArea() { | ||
if(this.svg) { | ||
if (this.svg) { | ||
this.container.removeChild(this.svg); | ||
@@ -190,3 +193,3 @@ } | ||
if(this.title.length) { | ||
if (this.title.length) { | ||
this.titleEL = makeText( | ||
@@ -211,3 +214,3 @@ 'title', | ||
if(this.config.showLegend) { | ||
if (this.config.showLegend) { | ||
top += this.height + m.paddings.bottom; | ||
@@ -220,5 +223,5 @@ this.legendArea = makeSVGGroup( | ||
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); } | ||
@@ -238,3 +241,3 @@ this.updateTipOffset(getLeftOffset(m), getTopOffset(m)); | ||
update(data) { | ||
if(!data) { | ||
if (!data) { | ||
console.error('No data to update.'); | ||
@@ -247,4 +250,4 @@ } | ||
render(components=this.components, animate=true) { | ||
if(this.config.isNavigable) { | ||
render(components = this.components, animate = true) { | ||
if (this.config.isNavigable) { | ||
// Remove all existing overlays | ||
@@ -259,3 +262,3 @@ this.overlays.map(o => o.parentNode.removeChild(o)); | ||
}); | ||
if(elementsToAnimate.length > 0) { | ||
if (elementsToAnimate.length > 0) { | ||
runSMILAnimation(this.container, this.svg, elementsToAnimate); | ||
@@ -273,3 +276,3 @@ setTimeout(() => { | ||
updateNav() { | ||
if(this.config.isNavigable) { | ||
if (this.config.isNavigable) { | ||
this.makeOverlay(); | ||
@@ -280,8 +283,27 @@ this.bindUnits(); | ||
renderLegend() {} | ||
renderLegend(dataset) { | ||
this.legendArea.textContent = ''; | ||
let count = 0; | ||
let y = 0; | ||
setupNavigation(init=false) { | ||
if(!this.config.isNavigable) return; | ||
dataset.map((data, index) => { | ||
let divisor = Math.floor(this.width / LEGEND_ITEM_WIDTH); | ||
if (count > divisor) { | ||
count = 0; | ||
y += this.config.legendRowHeight; | ||
} | ||
let x = LEGEND_ITEM_WIDTH * count; | ||
let dot = this.makeLegend(data, index, x, y); | ||
this.legendArea.appendChild(dot); | ||
count++; | ||
}); | ||
} | ||
if(init) { | ||
makeLegend() { } | ||
setupNavigation(init = false) { | ||
if (!this.config.isNavigable) return; | ||
if (init) { | ||
this.bindOverlay(); | ||
@@ -298,5 +320,5 @@ | ||
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](); | ||
@@ -309,20 +331,20 @@ } | ||
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() { } | ||
@@ -329,0 +351,0 @@ export() { |
@@ -1,18 +0,8 @@ | ||
import AggregationChart from './AggregationChart'; | ||
import PieChart from './PieChart'; | ||
import { getComponent } from '../objects/ChartComponents'; | ||
import { getOffset } from '../utils/dom'; | ||
import { getPositionByAngle } from '../utils/helpers'; | ||
import { makeArcStrokePathStr, makeStrokeCircleStr } from '../utils/draw'; | ||
import { lightenDarkenColor } from '../utils/colors'; | ||
import { transform } from '../utils/animation'; | ||
import { FULL_ANGLE } from '../utils/constants'; | ||
export default class DonutChart extends AggregationChart { | ||
export default class DonutChart extends PieChart { | ||
constructor(parent, args) { | ||
super(parent, args); | ||
this.type = 'donut'; | ||
this.initTimeout = 0; | ||
this.init = 1; | ||
this.setup(); | ||
} | ||
@@ -22,64 +12,16 @@ | ||
super.configure(args); | ||
this.mouseMove = this.mouseMove.bind(this); | ||
this.mouseLeave = this.mouseLeave.bind(this); | ||
this.hoverRadio = args.hoverRadio || 0.1; | ||
this.config.startAngle = args.startAngle || 0; | ||
this.type = 'donut'; | ||
this.sliceName = 'donutSlices'; | ||
this.clockWise = args.clockWise || false; | ||
this.arcFunc = makeArcStrokePathStr; | ||
this.shapeFunc = makeStrokeCircleStr; | ||
this.strokeWidth = args.strokeWidth || 30; | ||
} | ||
calc() { | ||
super.calc(); | ||
let s = this.state; | ||
this.radius = | ||
this.height > this.width | ||
? this.center.x - this.strokeWidth / 2 | ||
: this.center.y - this.strokeWidth / 2; | ||
const { radius, clockWise } = this; | ||
const prevSlicesProperties = s.slicesProperties || []; | ||
s.sliceStrings = []; | ||
s.slicesProperties = []; | ||
let curAngle = 180 - this.config.startAngle; | ||
s.sliceTotals.map((total, i) => { | ||
const startAngle = curAngle; | ||
const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE; | ||
const largeArc = originDiffAngle > 180 ? 1: 0; | ||
const diffAngle = clockWise ? -originDiffAngle : originDiffAngle; | ||
const endAngle = curAngle = curAngle + diffAngle; | ||
const startPosition = getPositionByAngle(startAngle, radius); | ||
const endPosition = getPositionByAngle(endAngle, radius); | ||
const prevProperty = this.init && prevSlicesProperties[i]; | ||
let curStart,curEnd; | ||
if(this.init) { | ||
curStart = prevProperty ? prevProperty.startPosition : startPosition; | ||
curEnd = prevProperty ? prevProperty.endPosition : startPosition; | ||
} else { | ||
curStart = startPosition; | ||
curEnd = endPosition; | ||
} | ||
const curPath = | ||
originDiffAngle === 360 | ||
? makeStrokeCircleStr(curStart, curEnd, this.center, this.radius, this.clockWise, largeArc) | ||
: makeArcStrokePathStr(curStart, curEnd, this.center, this.radius, this.clockWise, largeArc); | ||
s.sliceStrings.push(curPath); | ||
s.slicesProperties.push({ | ||
startPosition, | ||
endPosition, | ||
value: total, | ||
total: s.grandTotal, | ||
startAngle, | ||
endAngle, | ||
angle: diffAngle | ||
}); | ||
}); | ||
this.init = 0; | ||
getRadius() { | ||
return this.height > this.width | ||
? this.center.x - this.strokeWidth / 2 | ||
: this.center.y - this.strokeWidth / 2; | ||
} | ||
@@ -92,5 +34,5 @@ | ||
[ | ||
'donutSlices', | ||
{ }, | ||
function() { | ||
this.sliceName, | ||
{}, | ||
function () { | ||
return { | ||
@@ -111,54 +53,2 @@ sliceStrings: s.sliceStrings, | ||
} | ||
calTranslateByAngle(property){ | ||
const{ radius, hoverRadio } = this; | ||
const position = getPositionByAngle(property.startAngle+(property.angle / 2),radius); | ||
return `translate3d(${(position.x) * hoverRadio}px,${(position.y) * hoverRadio}px,0)`; | ||
} | ||
hoverSlice(path,i,flag,e){ | ||
if(!path) return; | ||
const color = this.colors[i]; | ||
if(flag) { | ||
transform(path, this.calTranslateByAngle(this.state.slicesProperties[i])); | ||
path.style.stroke = lightenDarkenColor(color, 50); | ||
let g_off = getOffset(this.svg); | ||
let x = e.pageX - g_off.left + 10; | ||
let y = e.pageY - g_off.top - 10; | ||
let title = (this.formatted_labels && this.formatted_labels.length > 0 | ||
? this.formatted_labels[i] : this.state.labels[i]) + ': '; | ||
let percent = (this.state.sliceTotals[i] * 100 / this.state.grandTotal).toFixed(1); | ||
this.tip.setValues(x, y, {name: title, value: percent + "%"}); | ||
this.tip.showTip(); | ||
} else { | ||
transform(path,'translate3d(0,0,0)'); | ||
this.tip.hideTip(); | ||
path.style.stroke = color; | ||
} | ||
} | ||
bindTooltip() { | ||
this.container.addEventListener('mousemove', this.mouseMove); | ||
this.container.addEventListener('mouseleave', this.mouseLeave); | ||
} | ||
mouseMove(e){ | ||
const target = e.target; | ||
let slices = this.components.get('donutSlices').store; | ||
let prevIndex = this.curActiveSliceIndex; | ||
let prevAcitve = this.curActiveSlice; | ||
if(slices.includes(target)) { | ||
let i = slices.indexOf(target); | ||
this.hoverSlice(prevAcitve, prevIndex,false); | ||
this.curActiveSlice = target; | ||
this.curActiveSliceIndex = i; | ||
this.hoverSlice(target, i, true, e); | ||
} else { | ||
this.mouseLeave(); | ||
} | ||
} | ||
mouseLeave(){ | ||
this.hoverSlice(this.curActiveSlice,this.curActiveSliceIndex,false); | ||
} | ||
} |
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'; | ||
@@ -52,15 +56,15 @@ const COL_WIDTH = HEATMAP_SQUARE_SIZE + HEATMAP_GUTTER_SIZE; | ||
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 = {}; | ||
@@ -109,3 +113,3 @@ Object.keys(data.dataPoints).forEach(timestampSec => { | ||
}, | ||
function() { | ||
function () { | ||
return s.domainConfigs[i]; | ||
@@ -125,4 +129,4 @@ }.bind(this) | ||
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, | ||
{ | ||
@@ -141,3 +145,3 @@ fontSize: HEATMAP_SQUARE_SIZE, | ||
update(data) { | ||
if(!data) { | ||
if (!data) { | ||
console.error('No data to update.'); | ||
@@ -156,3 +160,3 @@ } | ||
let daySquare = e.target; | ||
if(daySquares.includes(daySquare)) { | ||
if (daySquares.includes(daySquare)) { | ||
@@ -162,3 +166,3 @@ let count = daySquare.getAttribute('data-value'); | ||
let month = getMonthName(parseInt(dateParts[1])-1, true); | ||
let month = getMonthName(parseInt(dateParts[1]) - 1, true); | ||
@@ -168,3 +172,3 @@ 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; | ||
@@ -174,3 +178,3 @@ let value = count + ' ' + this.countLabel; | ||
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(); | ||
@@ -194,3 +198,3 @@ } | ||
); | ||
x = (COL_WIDTH * 2) + COL_WIDTH/2; | ||
x = (COL_WIDTH * 2) + COL_WIDTH / 2; | ||
this.legendArea.appendChild(lessText); | ||
@@ -204,3 +208,3 @@ | ||
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', | ||
@@ -225,5 +229,5 @@ { | ||
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()]; | ||
@@ -241,3 +245,3 @@ endDate = getLastDateInMonth(month, year); | ||
getDomainConfig(startDate, endDate='') { | ||
getDomainConfig(startDate, endDate = '') { | ||
let [month, year] = [startDate.getMonth(), startDate.getFullYear()]; | ||
@@ -256,3 +260,3 @@ let startOfWeek = setDayToSunday(startDate); // TODO: Monday as well | ||
let cols = [], col; | ||
for(var i = 0; i < noOfMonthWeeks; i++) { | ||
for (var i = 0; i < noOfMonthWeeks; i++) { | ||
col = this.getCol(startOfWeek, month); | ||
@@ -265,3 +269,3 @@ cols.push(col); | ||
if(col[NO_OF_DAYS_IN_WEEK - 1].dataValue !== undefined) { | ||
if (col[NO_OF_DAYS_IN_WEEK - 1].dataValue !== undefined) { | ||
addDays(startOfWeek, 1); | ||
@@ -283,3 +287,3 @@ cols.push(this.getCol(startOfWeek, month, true)); | ||
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 = {}; | ||
@@ -290,3 +294,3 @@ | ||
if(empty || currentDate.getMonth() !== month || !currentDateWithinData) { | ||
if (empty || currentDate.getMonth() !== month || !currentDateWithinData) { | ||
config.yyyyMmDd = getYyyyMmDd(currentDate); | ||
@@ -293,0 +297,0 @@ } else { |
import AggregationChart from './AggregationChart'; | ||
import { getOffset } from '../utils/dom'; | ||
import { getComponent } from '../objects/ChartComponents'; | ||
import { PERCENTAGE_BAR_DEFAULT_HEIGHT, PERCENTAGE_BAR_DEFAULT_DEPTH } from '../utils/constants'; | ||
import { PERCENTAGE_BAR_DEFAULT_HEIGHT, getExtraHeight } from '../utils/constants'; | ||
@@ -19,7 +19,9 @@ export default class PercentageChart extends AggregationChart { | ||
b.height = b.height || PERCENTAGE_BAR_DEFAULT_HEIGHT; | ||
b.depth = b.depth || PERCENTAGE_BAR_DEFAULT_DEPTH; | ||
m.paddings.right = 30; | ||
m.legendHeight = 60; | ||
m.baseHeight = (b.height + b.depth * 0.5) * 8; | ||
m.paddings.top = 60; | ||
m.paddings.bottom = 0; | ||
m.legendHeight = 80; | ||
m.baseHeight = (b.height) * 8 + getExtraHeight(m); | ||
} | ||
@@ -35,5 +37,4 @@ | ||
barHeight: this.barOptions.height, | ||
barDepth: this.barOptions.depth, | ||
}, | ||
function() { | ||
function () { | ||
return { | ||
@@ -78,14 +79,15 @@ xPositions: s.xPositions, | ||
let bar = e.target; | ||
if(bars.includes(bar)) { | ||
if (bars.includes(bar)) { | ||
let i = bars.indexOf(bar); | ||
let gOff = getOffset(this.container), pOff = getOffset(bar); | ||
let x = pOff.left - gOff.left + parseInt(bar.getAttribute('width'))/2; | ||
let width = bar.getAttribute('width') || bar.getBoundingClientRect().width; | ||
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(); | ||
@@ -92,0 +94,0 @@ } |
@@ -6,3 +6,2 @@ import AggregationChart from './AggregationChart'; | ||
import { makeArcPathStr, makeCircleStr } from '../utils/draw'; | ||
import { lightenDarkenColor } from '../utils/colors'; | ||
import { transform } from '../utils/animation'; | ||
@@ -14,3 +13,2 @@ import { FULL_ANGLE } from '../utils/constants'; | ||
super(parent, args); | ||
this.type = 'pie'; | ||
this.initTimeout = 0; | ||
@@ -30,9 +28,19 @@ this.init = 1; | ||
this.type = 'pie'; | ||
this.sliceName = 'pieSlices'; | ||
this.arcFunc = makeArcPathStr; | ||
this.shapeFunc = makeCircleStr; | ||
this.clockWise = args.clockWise || false; | ||
} | ||
getRadius() { | ||
return this.height > this.width ? this.center.x : this.center.y; | ||
} | ||
calc() { | ||
super.calc(); | ||
let s = this.state; | ||
this.radius = (this.height > this.width ? this.center.x : this.center.y); | ||
this.radius = this.getRadius(); | ||
@@ -48,3 +56,3 @@ const { radius, clockWise } = this; | ||
const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE; | ||
const largeArc = originDiffAngle > 180 ? 1: 0; | ||
const largeArc = originDiffAngle > 180 ? 1 : 0; | ||
const diffAngle = clockWise ? -originDiffAngle : originDiffAngle; | ||
@@ -57,4 +65,4 @@ const endAngle = curAngle = curAngle + diffAngle; | ||
let curStart,curEnd; | ||
if(this.init) { | ||
let curStart, curEnd; | ||
if (this.init) { | ||
curStart = prevProperty ? prevProperty.startPosition : startPosition; | ||
@@ -68,4 +76,4 @@ curEnd = prevProperty ? prevProperty.endPosition : startPosition; | ||
originDiffAngle === 360 | ||
? makeCircleStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc) | ||
: makeArcPathStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc); | ||
? this.shapeFunc(curStart, curEnd, this.center, this.radius, clockWise, largeArc) | ||
: this.arcFunc(curStart, curEnd, this.center, this.radius, clockWise, largeArc); | ||
@@ -93,4 +101,4 @@ s.sliceStrings.push(curPath); | ||
'pieSlices', | ||
{ }, | ||
function() { | ||
{}, | ||
function () { | ||
return { | ||
@@ -111,14 +119,15 @@ sliceStrings: s.sliceStrings, | ||
calTranslateByAngle(property){ | ||
const{radius,hoverRadio} = this; | ||
const position = getPositionByAngle(property.startAngle+(property.angle / 2),radius); | ||
calTranslateByAngle(property) { | ||
const { radius, hoverRadio } = this; | ||
const position = getPositionByAngle(property.startAngle + (property.angle / 2), radius); | ||
return `translate3d(${(position.x) * hoverRadio}px,${(position.y) * hoverRadio}px,0)`; | ||
} | ||
hoverSlice(path,i,flag,e){ | ||
if(!path) return; | ||
hoverSlice(path, i, flag, e) { | ||
if (!path) return; | ||
const color = this.colors[i]; | ||
if(flag) { | ||
if (flag) { | ||
transform(path, this.calTranslateByAngle(this.state.slicesProperties[i])); | ||
path.style.fill = lightenDarkenColor(color, 50); | ||
// path.style.fill = lightenDarkenColor(color, 50); | ||
// path.style.stroke = lightenDarkenColor(color, 50); | ||
let g_off = getOffset(this.svg); | ||
@@ -130,6 +139,6 @@ let x = e.pageX - g_off.left + 10; | ||
let percent = (this.state.sliceTotals[i] * 100 / this.state.grandTotal).toFixed(1); | ||
this.tip.setValues(x, y, {name: title, value: percent + "%"}); | ||
this.tip.setValues(x, y, { name: title, value: percent + "%" }); | ||
this.tip.showTip(); | ||
} else { | ||
transform(path,'translate3d(0,0,0)'); | ||
transform(path, 'translate3d(0,0,0)'); | ||
this.tip.hideTip(); | ||
@@ -145,10 +154,10 @@ path.style.fill = color; | ||
mouseMove(e){ | ||
mouseMove(e) { | ||
const target = e.target; | ||
let slices = this.components.get('pieSlices').store; | ||
let slices = this.components.get(this.sliceName).store; | ||
let prevIndex = this.curActiveSliceIndex; | ||
let prevAcitve = this.curActiveSlice; | ||
if(slices.includes(target)) { | ||
let prevActive = this.curActiveSlice; | ||
if (slices.includes(target)) { | ||
let i = slices.indexOf(target); | ||
this.hoverSlice(prevAcitve, prevIndex,false); | ||
this.hoverSlice(prevActive, prevIndex, false); | ||
this.curActiveSlice = target; | ||
@@ -162,5 +171,5 @@ this.curActiveSliceIndex = i; | ||
mouseLeave(){ | ||
this.hoverSlice(this.curActiveSlice,this.curActiveSliceIndex,false); | ||
mouseLeave() { | ||
this.hoverSlice(this.curActiveSlice, this.curActiveSliceIndex, false); | ||
} | ||
} |
@@ -6,3 +6,3 @@ import * as Charts from './chart'; | ||
frappe.NAME = 'Frappe Charts'; | ||
frappe.VERSION = '1.5.5'; | ||
frappe.VERSION = '2.0.0-rc1'; | ||
@@ -9,0 +9,0 @@ frappe = Object.assign({ }, frappe, Charts); |
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'; | ||
@@ -30,3 +32,3 @@ | ||
this.layerClass = layerClass; | ||
this.layerClass = typeof(this.layerClass) === 'function' | ||
this.layerClass = typeof (this.layerClass) === 'function' | ||
? this.layerClass() : this.layerClass; | ||
@@ -65,3 +67,3 @@ | ||
let animateElements = []; | ||
if(animate) { | ||
if (animate) { | ||
animateElements = this.animateElements(this.data) || []; | ||
@@ -91,3 +93,3 @@ } | ||
makeElements(data) { | ||
return data.sliceStrings.map((s, i) =>{ | ||
return data.sliceStrings.map((s, i) => { | ||
let slice = makePath(s, 'pie-path', 'none', data.colors[i]); | ||
@@ -108,6 +110,10 @@ slice.style.transition = 'transform .3s;'; | ||
makeElements(data) { | ||
return data.xPositions.map((x, i) =>{ | ||
const numberOfPoints = data.xPositions.length; | ||
return data.xPositions.map((x, i) => { | ||
let y = 0; | ||
let bar = percentageBar(x, y, data.widths[i], | ||
this.constants.barHeight, this.constants.barDepth, data.colors[i]); | ||
let isLast = i == numberOfPoints - 1; | ||
let isFirst = i == 0; | ||
let bar = percentageBar(x, y, data.widths[i], this.constants.barHeight, isFirst, isLast, data.colors[i]); | ||
return bar; | ||
@@ -118,3 +124,3 @@ }); | ||
animateElements(newData) { | ||
if(newData) return []; | ||
if (newData) return []; | ||
} | ||
@@ -127,3 +133,3 @@ }, | ||
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 }) | ||
); | ||
@@ -159,3 +165,3 @@ }, | ||
xLine(position, data.calcLabels[i], this.constants.height, | ||
{mode: this.constants.mode, pos: this.constants.pos}) | ||
{ mode: this.constants.mode, pos: this.constants.pos }) | ||
); | ||
@@ -191,3 +197,3 @@ }, | ||
yMarker(m.position, m.label, this.constants.width, | ||
{labelPos: m.options.labelPos, mode: 'span', lineType: 'dashed'}) | ||
{ labelPos: m.options.labelPos, stroke: m.options.stroke, mode: 'span', lineType: 'dashed' }) | ||
); | ||
@@ -225,3 +231,3 @@ }, | ||
yRegion(r.startPos, r.endPos, this.constants.width, | ||
r.label, {labelPos: r.options.labelPos}) | ||
r.label, { labelPos: r.options.labelPos, stroke: r.options.stroke, fill: r.options.fill }) | ||
); | ||
@@ -262,5 +268,5 @@ }, | ||
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; | ||
@@ -272,3 +278,3 @@ let x = xTranslate, y = 0; | ||
data.cols.map((week, weekNo) => { | ||
if(weekNo === 1) { | ||
if (weekNo === 1) { | ||
this.labels.push( | ||
@@ -283,3 +289,3 @@ makeText('domain-name', x, monthNameHeight, getMonthName(index, true).toUpperCase(), | ||
week.map((day, i) => { | ||
if(day.fill) { | ||
if (day.fill) { | ||
let data = { | ||
@@ -303,3 +309,3 @@ 'data-date': day.yyyyMmDd, | ||
animateElements(newData) { | ||
if(newData) return []; | ||
if (newData) return []; | ||
} | ||
@@ -309,3 +315,3 @@ }, | ||
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) { | ||
@@ -364,3 +370,3 @@ let c = this.constants; | ||
bar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i], | ||
{zeroLine: newData.zeroLine} | ||
{ zeroLine: newData.zeroLine } | ||
)); | ||
@@ -374,3 +380,3 @@ }); | ||
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) { | ||
@@ -380,3 +386,3 @@ let c = this.constants; | ||
this.paths = {}; | ||
if(!c.hideLine) { | ||
if (!c.hideLine) { | ||
this.paths = getPaths( | ||
@@ -399,3 +405,3 @@ data.xPositions, | ||
this.units = []; | ||
if(!c.hideDots) { | ||
if (c.showDots) { | ||
this.units = data.yPositions.map((y, j) => { | ||
@@ -439,3 +445,3 @@ return datasetDot( | ||
if(Object.keys(this.paths).length) { | ||
if (Object.keys(this.paths).length) { | ||
animateElements = animateElements.concat(animatePath( | ||
@@ -445,3 +451,3 @@ this.paths, newXPos, newYPos, newData.zeroLine, this.constants.spline)); | ||
if(this.units.length) { | ||
if (this.units.length) { | ||
this.units.map((dot, i) => { | ||
@@ -448,0 +454,0 @@ animateElements = animateElements.concat(animateDot( |
@@ -45,2 +45,3 @@ import { $ } from '../utils/dom'; | ||
this.title = this.container.querySelector('.title'); | ||
this.list = this.container.querySelector('.data-point-list'); | ||
this.dataPointList = this.container.querySelector('.data-point-list'); | ||
@@ -55,6 +56,6 @@ | ||
let title; | ||
if(this.index) { | ||
if (this.index) { | ||
this.container.setAttribute('data-point-index', this.index); | ||
} | ||
if(this.titleValueFirst) { | ||
if (this.titleValueFirst) { | ||
title = `<strong>${this.titleValue}</strong>${this.titleName}`; | ||
@@ -64,2 +65,9 @@ } else { | ||
} | ||
if (this.listValues.length > 4) { | ||
this.list.classList.add('tooltip-grid'); | ||
} else { | ||
this.list.classList.remove('tooltip-grid'); | ||
} | ||
this.title.innerHTML = title; | ||
@@ -71,9 +79,8 @@ this.dataPointList.innerHTML = ''; | ||
let value = set.formatted === 0 || set.formatted ? set.formatted : set.value; | ||
let li = $.create('li', { | ||
styles: { | ||
'border-top': `3px solid ${color}` | ||
}, | ||
innerHTML: `<strong style="display: block;">${ value === 0 || value ? value : '' }</strong> | ||
${set.title ? set.title : '' }` | ||
innerHTML: `<div class="tooltip-legend" style="background: ${color};"></div> | ||
<div> | ||
<div class="tooltip-value">${value === 0 || value ? value : ''}</div> | ||
<div class="tooltip-label">${set.title ? set.title : ''}</div> | ||
</div>` | ||
}); | ||
@@ -90,3 +97,3 @@ | ||
- TOOLTIP_POINTER_TRIANGLE_HEIGHT; | ||
this.left = this.x - width/2; | ||
this.left = this.x - width / 2; | ||
let maxLeft = this.parent.offsetWidth - width; | ||
@@ -96,6 +103,6 @@ | ||
if(this.left < 0) { | ||
if (this.left < 0) { | ||
pointer.style.left = `calc(50% - ${-1 * this.left}px)`; | ||
this.left = 0; | ||
} else if(this.left > maxLeft) { | ||
} else if (this.left > maxLeft) { | ||
let delta = this.left - maxLeft; | ||
@@ -102,0 +109,0 @@ let pointerOffset = `calc(50% + ${delta}px)`; |
@@ -14,7 +14,7 @@ import { getBarHeightAndYAttr, getSplineCurvePointsStr } from './draw-utils'; | ||
unit, | ||
{transform: newCoord.join(', ')}, | ||
{ transform: newCoord.join(', ') }, | ||
duration, | ||
STD_EASING, | ||
"translate", | ||
{transform: old} | ||
{ transform: old } | ||
]; | ||
@@ -46,10 +46,10 @@ } | ||
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, | ||
@@ -63,3 +63,3 @@ STD_EASING | ||
} 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]]; | ||
} | ||
@@ -70,3 +70,3 @@ // 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); | ||
@@ -76,3 +76,3 @@ let groupAnim = translate(dot, oldCoordStr, [x, y], MARKER_LINE_ANIM_DUR); | ||
} else { | ||
return [[dot, {cx: x, cy: y}, UNIT_ANIM_DUR, STD_EASING]]; | ||
return [[dot, { cx: x, cy: y }, UNIT_ANIM_DUR, STD_EASING]]; | ||
} | ||
@@ -89,6 +89,6 @@ // dot.animate({cy: yTop}, UNIT_ANIM_DUR, mina.easein); | ||
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`; | ||
@@ -99,3 +99,3 @@ let regEndPt = `L${newXList.slice(-1)[0]}, ${zeroLine}`; | ||
paths.region, | ||
{d:"M" + regStartPt + pointsStr + regEndPt}, | ||
{ d: "M" + regStartPt + pointsStr + regEndPt }, | ||
PATH_ANIM_DUR, | ||
@@ -111,3 +111,3 @@ STD_EASING | ||
export function animatePathStr(oldPath, pathStr) { | ||
return [oldPath, {d: pathStr}, UNIT_ANIM_DUR, STD_EASING]; | ||
return [oldPath, { d: pathStr }, UNIT_ANIM_DUR, STD_EASING]; | ||
} |
@@ -14,3 +14,3 @@ // Leveraging SMIL Animations | ||
function animateSVGElement(element, props, dur, easingType="linear", type=undefined, oldValues={}) { | ||
function animateSVGElement(element, props, dur, easingType = "linear", type = undefined, oldValues = {}) { | ||
@@ -20,5 +20,5 @@ let animElement = 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"); | ||
@@ -36,3 +36,3 @@ } else { | ||
begin: "0s", | ||
dur: dur/1000 + "s", | ||
dur: dur / 1000 + "s", | ||
values: currentValue + ";" + value, | ||
@@ -45,3 +45,3 @@ keySplines: EASING[easingType], | ||
if(type) { | ||
if (type) { | ||
animAttr["type"] = type; | ||
@@ -56,3 +56,3 @@ } | ||
if(type) { | ||
if (type) { | ||
newElement.setAttribute(attributeName, `translate(${value})`); | ||
@@ -105,6 +105,6 @@ } else { | ||
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); | ||
@@ -117,3 +117,3 @@ parent.appendChild(animSvgElement); | ||
setTimeout(() => { | ||
if(animSvgElement.parentNode == parent) { | ||
if (animSvgElement.parentNode == parent) { | ||
parent.removeChild(animSvgElement); | ||
@@ -120,0 +120,0 @@ parent.appendChild(svgElement); |
import { fillArray } from '../utils/helpers'; | ||
import { DEFAULT_AXIS_CHART_TYPE, AXIS_DATASET_CHART_TYPES, DEFAULT_CHAR_WIDTH } from '../utils/constants'; | ||
import { | ||
DEFAULT_AXIS_CHART_TYPE, AXIS_DATASET_CHART_TYPES, DEFAULT_CHAR_WIDTH, | ||
SERIES_LABEL_SPACE_RATIO | ||
} from '../utils/constants'; | ||
@@ -12,3 +15,3 @@ export function dataPrep(data, type) { | ||
let zeroArray = new Array(datasetLength).fill(0); | ||
if(!datasets) { | ||
if (!datasets) { | ||
// default | ||
@@ -20,5 +23,5 @@ datasets = [{ | ||
datasets.map(d=> { | ||
datasets.map(d => { | ||
// Set values | ||
if(!d.values) { | ||
if (!d.values) { | ||
d.values = zeroArray; | ||
@@ -31,3 +34,3 @@ } else { | ||
// Trim or extend | ||
if(vals.length > datasetLength) { | ||
if (vals.length > datasetLength) { | ||
vals = vals.slice(0, datasetLength); | ||
@@ -43,4 +46,4 @@ } else { | ||
// 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; | ||
@@ -55,5 +58,5 @@ } | ||
// 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]; | ||
@@ -82,3 +85,3 @@ } | ||
if(realData.yMarkers) { | ||
if (realData.yMarkers) { | ||
zeroData.yMarkers = [ | ||
@@ -92,3 +95,3 @@ { | ||
if(realData.yRegions) { | ||
if (realData.yRegions) { | ||
zeroData.yRegions = [ | ||
@@ -106,12 +109,12 @@ { | ||
export function getShortenedLabels(chartWidth, labels=[], isSeries=true) { | ||
let allowedSpace = chartWidth / labels.length; | ||
if(allowedSpace <= 0) allowedSpace = 1; | ||
export function getShortenedLabels(chartWidth, labels = [], isSeries = true) { | ||
let allowedSpace = (chartWidth / labels.length) * SERIES_LABEL_SPACE_RATIO; | ||
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); | ||
} | ||
@@ -121,7 +124,7 @@ | ||
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 { | ||
@@ -131,3 +134,3 @@ label = label.slice(0, allowedLetters) + '..'; | ||
} else { | ||
if(i % seriesMultiple !== 0) { | ||
if (i % seriesMultiple !== 0 && i !== (labels.length - 1)) { | ||
label = ""; | ||
@@ -134,0 +137,0 @@ } |
const PRESET_COLOR_MAP = { | ||
'light-blue': '#7cd6fd', | ||
'blue': '#5e64ff', | ||
'violet': '#743ee2', | ||
'red': '#ff5858', | ||
'orange': '#ffa00a', | ||
'yellow': '#feef72', | ||
'green': '#28a745', | ||
'light-green': '#98d85b', | ||
'purple': '#b554ff', | ||
'magenta': '#ffa3ef', | ||
'black': '#36114C', | ||
'grey': '#bdd3e6', | ||
'light-grey': '#f0f4f7', | ||
'dark-grey': '#b8c2cc' | ||
'pink': '#F683AE', | ||
'blue': '#318AD8', | ||
'green': '#48BB74', | ||
'grey': '#A6B1B9', | ||
'red': '#F56B6B', | ||
'yellow': '#FACF7A', | ||
'purple': '#44427B', | ||
'teal': '#5FD8C4', | ||
'cyan': '#15CCEF', | ||
'orange': '#F8814F', | ||
'light-pink': '#FED7E5', | ||
'light-blue': '#BFDDF7', | ||
'light-green': '#48BB74', | ||
'light-grey': '#F4F5F6', | ||
'light-red': '#F6DFDF', | ||
'light-yellow': '#FEE9BF', | ||
'light-purple': '#E8E8F7', | ||
'light-teal': '#D3FDF6', | ||
'light-cyan': '#DDF8FD', | ||
'light-orange': '#FECDB8' | ||
}; | ||
function limitColor(r){ | ||
function limitColor(r) { | ||
if (r > 255) return 255; | ||
@@ -31,7 +37,7 @@ else if (r < 0) return 0; | ||
} | ||
let num = parseInt(col,16); | ||
let num = parseInt(col, 16); | ||
let r = limitColor((num >> 16) + amt); | ||
let b = limitColor(((num >> 8) & 0x00FF) + amt); | ||
let g = limitColor((num & 0x0000FF) + amt); | ||
return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16); | ||
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16); | ||
} | ||
@@ -38,0 +44,0 @@ |
@@ -68,3 +68,4 @@ export const ALL_CHART_TYPES = ['line', 'scatter', 'bar', 'percentage', 'heatmap', 'pie']; | ||
export const AXIS_LEGEND_BAR_SIZE = 100; | ||
export const LEGEND_ITEM_WIDTH = 150; | ||
export const SERIES_LABEL_SPACE_RATIO = 0.6; | ||
@@ -77,4 +78,3 @@ export const BAR_CHART_SPACE_RATIO = 0.5; | ||
export const PERCENTAGE_BAR_DEFAULT_HEIGHT = 20; | ||
export const PERCENTAGE_BAR_DEFAULT_DEPTH = 2; | ||
export const PERCENTAGE_BAR_DEFAULT_HEIGHT = 16; | ||
@@ -90,6 +90,4 @@ // Fixed 5-color theme, | ||
export const TOOLTIP_POINTER_TRIANGLE_HEIGHT = 5; | ||
const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | ||
'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | ||
export const TOOLTIP_POINTER_TRIANGLE_HEIGHT = 7.48; | ||
const DEFAULT_CHART_COLORS = ['pink', 'blue', 'green', 'grey', 'red', 'yellow', 'purple', 'teal', 'cyan', 'orange']; | ||
const HEATMAP_COLORS_GREEN = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | ||
@@ -96,0 +94,0 @@ export const HEATMAP_COLORS_BLUE = ['#ebedf0', '#c0ddf9', '#73b3f3', '#3886e1', '#17459e']; |
@@ -30,4 +30,4 @@ // Playing around with dates | ||
date.getFullYear(), | ||
(mm>9 ? '' : '0') + mm, | ||
(dd>9 ? '' : '0') + dd | ||
(mm > 9 ? '' : '0') + mm, | ||
(dd > 9 ? '' : '0') + dd | ||
].join('-'); | ||
@@ -41,3 +41,3 @@ } | ||
export function timestampSec(date) { | ||
return date.getTime()/NO_OF_MILLIS; | ||
return date.getTime() / NO_OF_MILLIS; | ||
} | ||
@@ -47,3 +47,3 @@ | ||
let midnightTs = Math.floor(timestamp - (timestamp % SEC_IN_DAY)); | ||
if(roundAhead) { | ||
if (roundAhead) { | ||
return midnightTs + SEC_IN_DAY; | ||
@@ -71,3 +71,3 @@ } | ||
export function getMonthName(i, short=false) { | ||
export function getMonthName(i, short = false) { | ||
let monthName = MONTH_NAMES[i]; | ||
@@ -77,3 +77,3 @@ 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 | ||
@@ -86,3 +86,3 @@ } | ||
const day = newDate.getDay(); | ||
if(day !== 0) { | ||
if (day !== 0) { | ||
addDays(newDate, (-1) * day); | ||
@@ -89,0 +89,0 @@ } |
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; | ||
@@ -30,3 +29,3 @@ while (node.previousSibling) { | ||
} else if (i === "styles") { | ||
if(typeof val === "object") { | ||
if (typeof val === "object") { | ||
Object.keys(val).map(prop => { | ||
@@ -36,3 +35,3 @@ element.style[prop] = val[prop]; | ||
} | ||
} else if (i in element ) { | ||
} else if (i in element) { | ||
element[i] = val; | ||
@@ -72,5 +71,5 @@ } | ||
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() */ | ||
); | ||
@@ -87,3 +86,3 @@ } | ||
export function bind(element, o){ | ||
export function bind(element, o) { | ||
if (element) { | ||
@@ -100,3 +99,3 @@ for (var event in o) { | ||
export function unbind(element, o){ | ||
export function unbind(element, o) { | ||
if (element) { | ||
@@ -106,3 +105,3 @@ for (var event in o) { | ||
event.split(/\s+/).forEach(function(event) { | ||
event.split(/\s+/).forEach(function (event) { | ||
element.removeEventListener(event, callback); | ||
@@ -117,3 +116,3 @@ }); | ||
evt.initEvent(type, true, true ); | ||
evt.initEvent(type, true, true); | ||
@@ -129,3 +128,3 @@ for (var j in properties) { | ||
export function forEachNode(nodeList, callback, scope) { | ||
if(!nodeList) return; | ||
if (!nodeList) return; | ||
for (var i = 0; i < nodeList.length; i++) { | ||
@@ -136,7 +135,7 @@ 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); | ||
@@ -143,0 +142,0 @@ }); |
@@ -20,3 +20,3 @@ import { fillArray } from './helpers'; | ||
// Doesn't work if either has zero elements. | ||
if(extraCount > 0) { | ||
if (extraCount > 0) { | ||
array1 = fillArray(array1, extraCount); | ||
@@ -34,3 +34,3 @@ } else { | ||
if (txt.length > len) { | ||
return txt.slice(0, len-3) + '...'; | ||
return txt.slice(0, len - 3) + '...'; | ||
} else { | ||
@@ -52,7 +52,7 @@ return txt; | ||
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]; | ||
} | ||
@@ -63,4 +63,4 @@ | ||
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]]); | ||
@@ -78,3 +78,3 @@ } | ||
}; | ||
let controlPoint = (current, previous, next, reverse) => { | ||
@@ -90,3 +90,3 @@ let p = previous || current; | ||
}; | ||
let bezierCommand = (point, i, a) => { | ||
@@ -97,3 +97,3 @@ let cps = controlPoint(a[i - 1], a[i - 2], point); | ||
}; | ||
let pointStr = (points, command) => { | ||
@@ -104,4 +104,4 @@ return points.reduce((acc, point, i, a) => i === 0 | ||
}; | ||
return pointStr(points, bezierCommand); | ||
} |
import { getBarHeightAndYAttr, truncateString, shortenLargeNumber, getSplineCurvePointsStr } from './draw-utils'; | ||
import { getStringWidth, isValidNumber } from './helpers'; | ||
import { DOT_OVERLAY_SIZE_INCR, PERCENTAGE_BAR_DEFAULT_DEPTH } from './constants'; | ||
import { lightenDarkenColor } from './colors'; | ||
import { getStringWidth, isValidNumber, round } from './helpers'; | ||
import { DOT_OVERLAY_SIZE_INCR } from './constants'; | ||
export const AXIS_TICK_LENGTH = 6; | ||
const LABEL_MARGIN = 4; | ||
const LABEL_MAX_CHARS = 15; | ||
const LABEL_MAX_CHARS = 18; | ||
export const FONT_SIZE = 10; | ||
const BASE_LINE_COLOR = '#dadada'; | ||
const FONT_FILL = '#555b51'; | ||
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; | ||
} | ||
@@ -32,3 +31,3 @@ | ||
} else if (i === "styles") { | ||
if(typeof val === "object") { | ||
if (typeof val === "object") { | ||
Object.keys(val).map(prop => { | ||
@@ -39,4 +38,4 @@ 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; | ||
@@ -87,3 +86,3 @@ } else { | ||
export function makeSVGGroup(className, transform='', parent=undefined) { | ||
export function makeSVGGroup(className, transform = '', parent = undefined) { | ||
let args = { | ||
@@ -93,7 +92,7 @@ className: className, | ||
}; | ||
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', { | ||
@@ -106,3 +105,3 @@ className: className | ||
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', { | ||
@@ -119,3 +118,3 @@ className: className, | ||
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]; | ||
@@ -129,3 +128,3 @@ let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y]; | ||
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]; | ||
@@ -142,3 +141,3 @@ let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, center.y * 2, center.y + endPosition.y]; | ||
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]; | ||
@@ -152,3 +151,3 @@ let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y]; | ||
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]; | ||
@@ -166,7 +165,7 @@ let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, radius * 2 + arcStartY, center.y + startPosition.y]; | ||
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) { | ||
opacities = [0.4, 0.2, 0]; | ||
if (lighter) { | ||
opacities = [0.4, 0.05, 0]; | ||
} | ||
@@ -181,5 +180,28 @@ | ||
export function percentageBar(x, y, width, height, | ||
depth=PERCENTAGE_BAR_DEFAULT_DEPTH, fill='none') { | ||
export function rightRoundedBar(x, width, height) { | ||
// https://medium.com/@dennismphil/one-side-rounded-rectangle-using-svg-fb31cf318d90 | ||
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 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') { | ||
if (isLast) { | ||
let pathStr = rightRoundedBar(x, width, height); | ||
return makePath(pathStr, 'percentage-bar', null, fill); | ||
} | ||
if (isFirst) { | ||
let pathStr = leftRoundedBar(x, width, height); | ||
return makePath(pathStr, 'percentage-bar', null, fill); | ||
} | ||
let args = { | ||
@@ -191,10 +213,3 @@ className: 'percentage-bar', | ||
height: height, | ||
fill: fill, | ||
styles: { | ||
'stroke': lightenDarkenColor(fill, -25), | ||
// Diabolically good: https://stackoverflow.com/a/9000859 | ||
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray | ||
'stroke-dasharray': `0, ${height + width}, ${width}, ${height}`, | ||
'stroke-width': depth | ||
}, | ||
fill: fill | ||
}; | ||
@@ -205,3 +220,3 @@ | ||
export function heatSquare(className, x, y, size, radius, fill='none', data={}) { | ||
export function heatSquare(className, x, y, size, radius, fill = 'none', data = {}) { | ||
let args = { | ||
@@ -224,19 +239,23 @@ className: className, | ||
export function legendBar(x, y, size, fill='none', label, truncate=false) { | ||
export function legendDot(x, y, size, radius, fill = 'none', label, value, font_size = null, truncate = false) { | ||
label = truncate ? truncateString(label, LABEL_MAX_CHARS) : label; | ||
if (!font_size) font_size = FONT_SIZE; | ||
let args = { | ||
className: 'legend-bar', | ||
className: 'legend-dot', | ||
x: 0, | ||
y: 0, | ||
y: 4 - size, | ||
height: size, | ||
width: size, | ||
height: '2px', | ||
rx: radius, | ||
fill: fill | ||
}; | ||
let text = createSVG('text', { | ||
className: 'legend-dataset-text', | ||
x: 0, | ||
let textLabel = createSVG('text', { | ||
className: 'legend-dataset-label', | ||
x: size, | ||
y: 0, | ||
dy: (FONT_SIZE * 2) + 'px', | ||
'font-size': (FONT_SIZE * 1.2) + 'px', | ||
dx: (font_size) + 'px', | ||
dy: (font_size / 3) + 'px', | ||
'font-size': (font_size * 1.6) + 'px', | ||
'text-anchor': 'start', | ||
@@ -247,2 +266,17 @@ fill: FONT_FILL, | ||
let textValue = null; | ||
if (value) { | ||
textValue = createSVG('text', { | ||
className: 'legend-dataset-value', | ||
x: size, | ||
y: FONT_SIZE + 10, | ||
dx: (FONT_SIZE) + 'px', | ||
dy: (FONT_SIZE / 3) + 'px', | ||
'font-size': (FONT_SIZE * 1.2) + 'px', | ||
'text-anchor': 'start', | ||
fill: FONT_FILL, | ||
innerHTML: value | ||
}); | ||
} | ||
let group = createSVG('g', { | ||
@@ -252,35 +286,8 @@ transform: `translate(${x}, ${y})` | ||
group.appendChild(createSVG("rect", args)); | ||
group.appendChild(text); | ||
group.appendChild(textLabel); | ||
return group; | ||
} | ||
if (value && textValue) { | ||
group.appendChild(textValue); | ||
} | ||
export function legendDot(x, y, size, fill='none', label, truncate=false) { | ||
label = truncate ? truncateString(label, LABEL_MAX_CHARS) : label; | ||
let args = { | ||
className: 'legend-dot', | ||
cx: 0, | ||
cy: 0, | ||
r: size, | ||
fill: fill | ||
}; | ||
let text = createSVG('text', { | ||
className: 'legend-dataset-text', | ||
x: 0, | ||
y: 0, | ||
dx: (FONT_SIZE) + 'px', | ||
dy: (FONT_SIZE/3) + 'px', | ||
'font-size': (FONT_SIZE * 1.2) + 'px', | ||
'text-anchor': 'start', | ||
fill: FONT_FILL, | ||
innerHTML: label | ||
}); | ||
let group = createSVG('g', { | ||
transform: `translate(${x}, ${y})` | ||
}); | ||
group.appendChild(createSVG("circle", args)); | ||
group.appendChild(text); | ||
return group; | ||
@@ -306,4 +313,3 @@ } | ||
function makeVertLine(x, label, y1, y2, options={}) { | ||
if(!options.stroke) options.stroke = BASE_LINE_COLOR; | ||
function makeVertLine(x, label, y1, y2, options = {}) { | ||
let l = createSVG('line', { | ||
@@ -330,3 +336,3 @@ className: 'line-vertical ' + options.className, | ||
let line = createSVG('g', { | ||
transform: `translate(${ x }, 0)` | ||
transform: `translate(${x}, 0)` | ||
}); | ||
@@ -340,9 +346,8 @@ | ||
function makeHoriLine(y, label, x1, x2, options={}) { | ||
if(!options.stroke) options.stroke = BASE_LINE_COLOR; | ||
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" : ""); | ||
@@ -366,3 +371,3 @@ let l = createSVG('line', { | ||
'text-anchor': x1 < x2 ? 'end' : 'start', | ||
innerHTML: label+"" | ||
innerHTML: label + "" | ||
}); | ||
@@ -375,3 +380,3 @@ | ||
if(text === 0 || text === '0') { | ||
if (text === 0 || text === '0') { | ||
line.style.stroke = "rgba(27, 31, 35, 0.6)"; | ||
@@ -386,10 +391,10 @@ } | ||
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 = ''; | ||
@@ -399,3 +404,3 @@ let x1 = -1 * AXIS_TICK_LENGTH; | ||
if(options.mode === 'tick' && options.pos === 'right') { | ||
if (options.mode === 'tick' && options.pos === 'right') { | ||
x1 = width + AXIS_TICK_LENGTH; | ||
@@ -410,4 +415,5 @@ x2 = width; | ||
if (typeof label === "number") label = round(label); | ||
return makeHoriLine(y, label, x1, x2, { | ||
stroke: options.stroke, | ||
className: options.className, | ||
@@ -419,10 +425,9 @@ lineType: options.lineType, | ||
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.stroke) options.stroke = BASE_LINE_COLOR; | ||
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 = ''; | ||
@@ -443,3 +448,3 @@ // Draw X axis line in span/tick mode with optional label | ||
if(options.mode === 'tick' && options.pos === 'top') { | ||
if (options.mode === 'tick' && options.pos === 'top') { | ||
// top axis ticks | ||
@@ -451,3 +456,2 @@ y1 = -1 * AXIS_TICK_LENGTH; | ||
return makeVertLine(x, label, y1, y2, { | ||
stroke: options.stroke, | ||
className: options.className, | ||
@@ -458,4 +462,6 @@ lineType: options.lineType | ||
export function yMarker(y, label, width, options={}) { | ||
if(!options.labelPos) options.labelPos = 'right'; | ||
export function yMarker(y, label, width, options = {}) { | ||
if (!isValidNumber(y)) y = 0; | ||
if (!options.labelPos) options.labelPos = 'right'; | ||
let x = options.labelPos === 'left' ? LABEL_MARGIN | ||
@@ -471,3 +477,3 @@ : width - getStringWidth(label, 5) - LABEL_MARGIN; | ||
'text-anchor': 'start', | ||
innerHTML: label+"" | ||
innerHTML: label + "" | ||
}); | ||
@@ -486,3 +492,3 @@ | ||
export function yRegion(y1, y2, width, label, options={}) { | ||
export function yRegion(y1, y2, width, label, options = {}) { | ||
// return a group | ||
@@ -494,4 +500,4 @@ let height = y1 - y2; | ||
styles: { | ||
fill: `rgba(228, 234, 239, 0.49)`, | ||
stroke: BASE_LINE_COLOR, | ||
fill: options.fill || `rgba(228, 234, 239, 0.49)`, | ||
stroke: options.stroke || BASE_LINE_COLOR, | ||
'stroke-dasharray': `${width}, ${height}` | ||
@@ -506,5 +512,5 @@ }, | ||
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; | ||
@@ -518,3 +524,3 @@ let labelSvg = createSVG('text', { | ||
'text-anchor': 'start', | ||
innerHTML: label+"" | ||
innerHTML: label + "" | ||
}); | ||
@@ -532,7 +538,7 @@ | ||
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; | ||
@@ -548,2 +554,22 @@ y -= meta.minHeight; | ||
// x y h w | ||
// M{x},{y+r} | ||
// q0,-{r} {r},-{r} | ||
// q{r},0 {r},{r} | ||
// v{h-r} | ||
// h-{w}z | ||
// let radius = width/2; | ||
// let pathStr = `M${x},${y+radius} q0,-${radius} ${radius},-${radius} q${radius},0 ${radius},${radius} v${height-radius} h-${width}z` | ||
// let rect = createSVG('path', { | ||
// className: 'bar mini', | ||
// d: pathStr, | ||
// styles: { fill: color }, | ||
// x: x, | ||
// y: y, | ||
// 'data-point-index': index, | ||
// }); | ||
let rect = createSVG('rect', { | ||
@@ -561,3 +587,3 @@ className: `bar mini`, | ||
if(!label && !label.length) { | ||
if (!label && !label.length) { | ||
return rect; | ||
@@ -569,3 +595,3 @@ } else { | ||
className: 'data-point-value', | ||
x: width/2, | ||
x: width / 2, | ||
y: 0, | ||
@@ -589,3 +615,3 @@ dy: (FONT_SIZE / 2 * -1) + 'px', | ||
export function datasetDot(x, y, radius, color, label='', index=0) { | ||
export function datasetDot(x, y, radius, color, label = '', index = 0) { | ||
let dot = createSVG('circle', { | ||
@@ -601,3 +627,3 @@ style: `fill: ${color}`, | ||
if(!label && !label.length) { | ||
if (!label && !label.length) { | ||
return dot; | ||
@@ -629,3 +655,3 @@ } else { | ||
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)); | ||
@@ -638,6 +664,6 @@ let pointsStr = pointsList.join("L"); | ||
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); | ||
@@ -652,3 +678,3 @@ path.style.stroke = `url(#${gradient_id})`; | ||
// Region | ||
if(options.regionFill) { | ||
if (options.regionFill) { | ||
let gradient_id_region = makeGradient(meta.svgDefs, color, true); | ||
@@ -666,3 +692,3 @@ | ||
let transformValue; | ||
if(unit.nodeName !== 'rect') { | ||
if (unit.nodeName !== 'rect') { | ||
transformValue = unit.getAttribute('transform'); | ||
@@ -675,3 +701,3 @@ unit = unit.childNodes[0]; | ||
if(transformValue) { | ||
if (transformValue) { | ||
overlay.setAttribute('transform', transformValue); | ||
@@ -684,3 +710,3 @@ } | ||
let transformValue; | ||
if(unit.nodeName !== 'circle') { | ||
if (unit.nodeName !== 'circle') { | ||
transformValue = unit.getAttribute('transform'); | ||
@@ -696,3 +722,3 @@ unit = unit.childNodes[0]; | ||
if(transformValue) { | ||
if (transformValue) { | ||
overlay.setAttribute('transform', transformValue); | ||
@@ -705,3 +731,3 @@ } | ||
let transformValue; | ||
if(unit.nodeName !== 'circle') { | ||
if (unit.nodeName !== 'circle') { | ||
transformValue = unit.getAttribute('transform'); | ||
@@ -717,3 +743,3 @@ unit = unit.childNodes[0]; | ||
if(transformValue) { | ||
if (transformValue) { | ||
overlay.setAttribute('transform', transformValue); | ||
@@ -728,3 +754,3 @@ } | ||
let transformValue; | ||
if(unit.nodeName !== 'rect') { | ||
if (unit.nodeName !== 'rect') { | ||
transformValue = unit.getAttribute('transform'); | ||
@@ -740,3 +766,3 @@ unit = unit.childNodes[0]; | ||
if(transformValue) { | ||
if (transformValue) { | ||
overlay.setAttribute('transform', transformValue); | ||
@@ -748,3 +774,3 @@ } | ||
let transformValue; | ||
if(unit.nodeName !== 'circle') { | ||
if (unit.nodeName !== 'circle') { | ||
transformValue = unit.getAttribute('transform'); | ||
@@ -760,3 +786,3 @@ unit = unit.childNodes[0]; | ||
if(transformValue) { | ||
if (transformValue) { | ||
overlay.setAttribute('transform', transformValue); | ||
@@ -768,3 +794,3 @@ } | ||
let transformValue; | ||
if(unit.nodeName !== 'circle') { | ||
if (unit.nodeName !== 'circle') { | ||
transformValue = unit.getAttribute('transform'); | ||
@@ -780,3 +806,3 @@ unit = unit.childNodes[0]; | ||
if(transformValue) { | ||
if (transformValue) { | ||
overlay.setAttribute('transform', transformValue); | ||
@@ -783,0 +809,0 @@ } |
@@ -7,3 +7,3 @@ import { $ } from '../utils/dom'; | ||
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); | ||
@@ -14,3 +14,3 @@ a.href = url; | ||
a.click(); | ||
setTimeout(function(){ | ||
setTimeout(function () { | ||
document.body.removeChild(a); | ||
@@ -17,0 +17,0 @@ window.URL.revokeObjectURL(url); |
@@ -17,6 +17,6 @@ import { ANGLE_RATIO } from './constants'; | ||
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; | ||
}); | ||
@@ -50,4 +50,4 @@ return areEqual; | ||
*/ | ||
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]; | ||
@@ -66,3 +66,3 @@ } | ||
export function getStringWidth(string, charWidth) { | ||
return (string+"").length * charWidth; | ||
return (string + "").length * charWidth; | ||
} | ||
@@ -72,7 +72,7 @@ | ||
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(); | ||
@@ -105,3 +105,3 @@ return Reflect.get(target, prop); | ||
*/ | ||
export function isValidNumber(candidate, nonNegative=false) { | ||
export function isValidNumber(candidate, nonNegative = false) { | ||
if (Number.isNaN(candidate)) return false; | ||
@@ -122,2 +122,2 @@ else if (candidate === undefined) return false; | ||
return Number(Math.round(d + 'e4') + 'e-4'); | ||
} | ||
} |
@@ -8,11 +8,11 @@ import { floatTwo } from './helpers'; | ||
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 }; | ||
} | ||
@@ -22,3 +22,3 @@ | ||
var exp = Math.floor(Math.log10(x)); | ||
var man = x/Math.pow(10, exp); | ||
var man = x / Math.pow(10, exp); | ||
@@ -28,3 +28,3 @@ return [sig * man, exp]; | ||
function getChartRangeIntervals(max, min=0) { | ||
function getChartRangeIntervals(max, min = 0) { | ||
let upperBound = Math.ceil(max); | ||
@@ -38,4 +38,4 @@ let lowerBound = Math.floor(min); | ||
// To avoid too many partitions | ||
if(range > 5) { | ||
if(range % 2 !== 0) { | ||
if (range > 5) { | ||
if (range % 2 !== 0) { | ||
upperBound++; | ||
@@ -45,3 +45,3 @@ // Recalc range | ||
} | ||
noOfParts = range/2; | ||
noOfParts = range / 2; | ||
partSize = 2; | ||
@@ -51,9 +51,9 @@ } | ||
// 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; | ||
@@ -64,3 +64,3 @@ partSize = 1; | ||
let intervals = []; | ||
for(var i = 0; i <= noOfParts; i++){ | ||
for (var i = 0; i <= noOfParts; i++) { | ||
intervals.push(lowerBound + partSize * i); | ||
@@ -71,5 +71,5 @@ } | ||
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; | ||
@@ -84,3 +84,3 @@ // Allow only 7 significant digits | ||
export function calcChartIntervals(values, withMinimum=false) { | ||
export function calcChartIntervals(values, withMinimum = false) { | ||
//*** Where the magic happens *** | ||
@@ -104,3 +104,3 @@ | ||
let value = 0; | ||
for(var i = 1; value < absMinValue; i++) { | ||
for (var i = 1; value < absMinValue; i++) { | ||
value += intervalSize; | ||
@@ -114,5 +114,5 @@ intervals.unshift((-1) * value); | ||
if(maxValue >= 0 && minValue >= 0) { | ||
if (maxValue >= 0 && minValue >= 0) { | ||
exponent = normalize(maxValue)[1]; | ||
if(!withMinimum) { | ||
if (!withMinimum) { | ||
intervals = getChartIntervals(maxValue); | ||
@@ -126,3 +126,3 @@ } else { | ||
else if(maxValue > 0 && minValue < 0) { | ||
else if (maxValue > 0 && minValue < 0) { | ||
// `withMinimum` irrelevant in this case, | ||
@@ -136,3 +136,3 @@ // We'll be handling both sides of zero separately | ||
if(maxValue >= absMinValue) { | ||
if (maxValue >= absMinValue) { | ||
exponent = normalize(maxValue)[1]; | ||
@@ -151,3 +151,3 @@ intervals = getPositiveFirstIntervals(maxValue, absMinValue); | ||
else if(maxValue <= 0 && minValue <= 0) { | ||
else if (maxValue <= 0 && minValue <= 0) { | ||
// Mirrored Case I: | ||
@@ -160,3 +160,3 @@ // Work with positives, then reverse the sign and array | ||
exponent = normalize(pseudoMaxValue)[1]; | ||
if(!withMinimum) { | ||
if (!withMinimum) { | ||
intervals = getChartIntervals(pseudoMaxValue); | ||
@@ -176,7 +176,7 @@ } else { | ||
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 | ||
@@ -200,3 +200,3 @@ // zero-line is off the chart: below | ||
for(var i = 0; i <= noOfIntervals; i++) { | ||
for (var i = 0; i <= noOfIntervals; i++) { | ||
intervals.push(min + part * i); | ||
@@ -213,3 +213,3 @@ } | ||
export function getValueRange(orderedArray) { | ||
return orderedArray[orderedArray.length-1] - orderedArray[0]; | ||
return orderedArray[orderedArray.length - 1] - orderedArray[0]; | ||
} | ||
@@ -231,3 +231,3 @@ | ||
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); | ||
@@ -248,3 +248,3 @@ }, []); | ||
for(var i = 0; i < distributionSize; i++) { | ||
for (var i = 0; i < distributionSize; i++) { | ||
let checkpoint = dataMaxValue * (distributionStep * i); | ||
@@ -251,0 +251,0 @@ distribution.push(checkpoint); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10
Yes
902421
39
4473
2