frappe-charts
Advanced tools
Comparing version 2.0.0-rc2 to 2.0.0-rc20
{ | ||
"name": "frappe-charts", | ||
"version": "2.0.0-rc2", | ||
"main": "src/js/chart.js", | ||
"version": "2.0.0-rc20", | ||
"main": "dist/frappe-charts.esm.js", | ||
"module": "dist/frappe-charts.esm.js", | ||
@@ -6,0 +6,0 @@ "browser": "dist/frappe-charts.umd.js", |
import BaseChart from './BaseChart'; | ||
import { legendDot } from '../utils/draw'; | ||
import { round } from '../utils/helpers'; | ||
@@ -4,0 +5,0 @@ export default class AggregationChart extends BaseChart { |
@@ -43,2 +43,3 @@ import BaseChart from './BaseChart'; | ||
this.config.shortenYAxisNumbers = options.axisOptions.shortenYAxisNumbers || 0; | ||
this.config.yAxisRange = options.axisOptions.yAxisRange || {}, | ||
@@ -90,3 +91,3 @@ this.config.formatTooltipX = options.tooltipOptions.formatTooltipX; | ||
calcYAxisParameters(dataValues, withMinimum = 'false') { | ||
const yPts = calcChartIntervals(dataValues, withMinimum); | ||
const yPts = calcChartIntervals(dataValues, withMinimum, this.config.yAxisRange); | ||
const scaleMultiplier = this.height / getValueRange(yPts); | ||
@@ -117,3 +118,3 @@ const intervalHeight = getIntervalSize(yPts) * scaleMultiplier; | ||
return { | ||
name: d.name.replace(/<|>|&/g, (char) => char == '&' ? '&' : char == '<' ? '<' : '>'), | ||
name: d.name && d.name.replace(/<|>|&/g, (char) => char == '&' ? '&' : char == '<' ? '<' : '>'), | ||
index: i, | ||
@@ -308,2 +309,4 @@ chartType: d.chartType, | ||
showDots: this.lineOptions.showDots, | ||
trailingDot: this.lineOptions.trailingDot, | ||
hideDotBorder: this.lineOptions.hideDotBorder, | ||
hideLine: this.lineOptions.hideLine, | ||
@@ -310,0 +313,0 @@ |
@@ -12,5 +12,7 @@ import SvgTip from '../objects/SvgTip'; | ||
import { downloadFile, prepareForExport } from '../utils/export'; | ||
import { deepClone } from '../utils/helpers'; | ||
export default class BaseChart { | ||
constructor(parent, options) { | ||
options = deepClone(options); | ||
@@ -37,5 +39,6 @@ this.parent = typeof parent === 'string' | ||
showTooltip: 1, // calculate | ||
showLegend: 1, // calculate | ||
showLegend: (typeof options.showLegend !== 'undefined') ? options.showLegend : 1, | ||
isNavigable: options.isNavigable || 0, | ||
animate: (typeof options.animate !== 'undefined') ? options.animate : 1, | ||
disableEntryAnimation: options.disableEntryAnimation || 0, | ||
truncateLegends: options.truncateLegends || 1 | ||
@@ -97,2 +100,6 @@ }; | ||
this.boundDrawFn = () => this.draw(true); | ||
if (ResizeObserver) { | ||
this.resizeObserver = new ResizeObserver(this.boundDrawFn); | ||
this.resizeObserver.observe(this.parent); | ||
} | ||
window.addEventListener('resize', this.boundDrawFn); | ||
@@ -103,2 +110,3 @@ window.addEventListener('orientationchange', this.boundDrawFn); | ||
destroy() { | ||
if (this.resizeObserver) this.resizeObserver.disconnect(); | ||
window.removeEventListener('resize', this.boundDrawFn); | ||
@@ -160,7 +168,9 @@ window.removeEventListener('orientationchange', this.boundDrawFn); | ||
this.data = this.realData; | ||
setTimeout(() => { this.update(this.data); }, this.initTimeout); | ||
setTimeout(() => { this.update(this.data, true); }, this.initTimeout); | ||
} | ||
if (this.config.showLegend) { | ||
this.renderLegend(); | ||
} | ||
this.renderLegend(); | ||
this.setupNavigation(init); | ||
@@ -234,9 +244,10 @@ } | ||
update(data) { | ||
if (!data) { | ||
console.error('No data to update.'); | ||
} | ||
update(data, drawing = false) { | ||
if (!data) console.error('No data to update.'); | ||
if (!drawing) data = deepClone(data); | ||
const animate = drawing ? !this.config.disableEntryAnimation : this.config.animate; | ||
this.data = this.prepareData(data); | ||
this.calc(); // builds state | ||
this.render(this.components, this.config.animate); | ||
this.render(this.components, animate); | ||
} | ||
@@ -243,0 +254,0 @@ |
import PieChart from './PieChart'; | ||
import { getComponent } from '../objects/ChartComponents'; | ||
import { makeArcStrokePathStr, makeStrokeCircleStr } from '../utils/draw'; | ||
import { transform } from '../utils/animation'; | ||
@@ -28,2 +29,8 @@ export default class DonutChart extends PieChart { | ||
resetHover(path, color) { | ||
transform(path,'translate3d(0,0,0)'); | ||
this.tip.hideTip(); | ||
path.style.stroke = color; | ||
} | ||
setupComponents() { | ||
@@ -30,0 +37,0 @@ let s = this.state; |
@@ -134,8 +134,12 @@ import AggregationChart from './AggregationChart'; | ||
} else { | ||
transform(path, 'translate3d(0,0,0)'); | ||
this.tip.hideTip(); | ||
path.style.fill = color; | ||
this.resetHover(path, color) | ||
} | ||
} | ||
resetHover(path, color) { | ||
transform(path, 'translate3d(0,0,0)'); | ||
this.tip.hideTip(); | ||
path.style.fill = color; | ||
} | ||
bindTooltip() { | ||
@@ -142,0 +146,0 @@ this.container.addEventListener('mousemove', this.mouseMove); |
@@ -6,3 +6,3 @@ import * as Charts from './chart'; | ||
frappe.NAME = 'Frappe Charts'; | ||
frappe.VERSION = '2.0.0-rc2'; | ||
frappe.VERSION = '2.0.0-rc20'; | ||
@@ -9,0 +9,0 @@ frappe = Object.assign({ }, frappe, Charts); |
@@ -190,3 +190,3 @@ import { makeSVGGroup } from '../utils/draw'; | ||
yMarker(m.position, m.label, this.constants.width, | ||
{ labelPos: m.options.labelPos, stroke: m.options.stroke, mode: 'span', lineType: 'dashed' }) | ||
{ labelPos: m.options.labelPos, stroke: m.options.stroke, mode: 'span', lineType: m.options.lineType }) | ||
); | ||
@@ -388,3 +388,3 @@ }, | ||
this.units = []; | ||
this.units = []; | ||
if (c.showDots) { | ||
@@ -398,3 +398,4 @@ this.units = data.yPositions.map((y, j) => { | ||
(c.valuesOverPoints ? data.values[j] : ''), | ||
j | ||
j, | ||
c.hideDotBorder | ||
); | ||
@@ -404,2 +405,17 @@ }); | ||
if (c.trailingDot && !c.showDots) { | ||
const lastIndex = data.yPositions.length - 1; | ||
const dot = datasetDot( | ||
data.xPositions[lastIndex], | ||
data.yPositions[lastIndex], | ||
data.radius, | ||
c.color, | ||
(c.valuesOverPoints ? data.values[lastIndex] : ''), | ||
lastIndex, | ||
c.hideDotBorder | ||
); | ||
this.units.push(dot); | ||
} | ||
return Object.values(this.paths).concat(this.units); | ||
@@ -406,0 +422,0 @@ }, |
@@ -37,7 +37,5 @@ import { fillArray } from '../utils/helpers'; | ||
} | ||
d.values = vals; | ||
} | ||
// Set labels | ||
// | ||
// Set type | ||
@@ -126,4 +124,10 @@ if (!d.chartType) { | ||
} else { | ||
if (i % seriesMultiple !== 0 && i !== (labels.length - 1)) { | ||
label = ""; | ||
if (i % seriesMultiple !== 0) { | ||
if (i !== (labels.length - 1)) { | ||
label = ""; | ||
} | ||
} else { | ||
if (i > (labels.length - (seriesMultiple / 2))) { | ||
label = ""; | ||
} | ||
} | ||
@@ -130,0 +134,0 @@ } |
@@ -54,3 +54,3 @@ import { fillArray } from './helpers'; | ||
// 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]; | ||
} | ||
@@ -62,2 +62,4 @@ | ||
let points = []; | ||
const length = Math.min(xList.length, yList.length); | ||
for (let i = 0; i < xList.length; i++) { | ||
@@ -64,0 +66,0 @@ points.push([xList[i], yList[i]]); |
@@ -159,3 +159,3 @@ import { getBarHeightAndYAttr, truncateString, shortenLargeNumber, getSplineCurvePointsStr } from './draw-utils'; | ||
if (lighter) { | ||
opacities = [0.4, 0.05, 0]; | ||
opacities = [0.15, 0.05, 0]; | ||
} | ||
@@ -281,3 +281,3 @@ | ||
let dy = options.dy !== undefined ? options.dy : (fontSize / 2); | ||
let fill = options.fill || FONT_FILL; | ||
let fill = options.fill || "var(--charts-label-color)"; | ||
let textAnchor = options.textAnchor || 'start'; | ||
@@ -438,2 +438,3 @@ return createSVG('text', { | ||
if (!options.labelPos) options.labelPos = 'right'; | ||
if (!options.lineType) options.lineType = 'dashed'; | ||
let x = options.labelPos === 'left' ? LABEL_MARGIN | ||
@@ -578,5 +579,5 @@ : width - getStringWidth(label, 5) - LABEL_MARGIN; | ||
export function datasetDot(x, y, radius, color, label = '', index = 0) { | ||
export function datasetDot(x, y, radius, color, label = '', index = 0, hideDotBorder = false) { | ||
let dot = createSVG('circle', { | ||
style: `fill: ${color}`, | ||
style: `fill: ${color}; ${hideDotBorder ? `stroke: ${color}`: ''}`, | ||
'data-point-index': index, | ||
@@ -583,0 +584,0 @@ cx: x, |
@@ -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,28 @@ else if (candidate === undefined) return false; | ||
return Number(Math.round(d + 'e4') + 'e-4'); | ||
} | ||
} | ||
/** | ||
* Creates a deep clone of an object | ||
* @param {Object} candidate Any Object | ||
*/ | ||
export function deepClone(candidate) { | ||
let cloned, value, key; | ||
if (candidate instanceof Date) { | ||
return new Date(candidate.getTime()); | ||
} | ||
if (typeof candidate !== "object" || candidate === null) { | ||
return candidate; | ||
} | ||
cloned = Array.isArray(candidate) ? [] : {}; | ||
for (key in candidate) { | ||
value = candidate[key]; | ||
cloned[key] = deepClone(value); | ||
} | ||
return cloned; | ||
} |
@@ -76,3 +76,3 @@ import { floatTwo } from './helpers'; | ||
export function calcChartIntervals(values, withMinimum = false) { | ||
export function calcChartIntervals(values, withMinimum = false, range = {}) { | ||
//*** Where the magic happens *** | ||
@@ -86,2 +86,10 @@ | ||
if (range.max !== undefined) { | ||
maxValue = maxValue > range.max ? maxValue : range.max; | ||
} | ||
if (range.min !== undefined) { | ||
minValue = minValue < range.min ? minValue : range.min; | ||
} | ||
// Exponent to be used for pretty print | ||
@@ -88,0 +96,0 @@ let exponent = 0, intervals = []; // eslint-disable-line no-unused-vars |
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 too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
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
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
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
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
1717538
44
5475
0
1