Merge branch 'master' into patch-1

This commit is contained in:
Shivam Mishra 2019-08-11 21:12:30 +05:30 committed by GitHub
commit 2814d7e25b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1873 additions and 1184 deletions

View File

@ -136,7 +136,7 @@ const AXIS_DATASET_CHART_TYPES = ['line', 'bar'];
const AXIS_LEGEND_BAR_SIZE = 100; const AXIS_LEGEND_BAR_SIZE = 100;
const BAR_CHART_SPACE_RATIO = 0.5; const BAR_CHART_SPACE_RATIO = 0.5;
const MIN_BAR_PERCENT_HEIGHT = 0.01; const MIN_BAR_PERCENT_HEIGHT = 0.00;
const LINE_CHART_DOT_SIZE = 4; const LINE_CHART_DOT_SIZE = 4;
const DOT_OVERLAY_SIZE_INCR = 4; const DOT_OVERLAY_SIZE_INCR = 4;
@ -382,6 +382,35 @@ function equilizeNoOfElements(array1, array2,
return [array1, array2]; return [array1, array2];
} }
function truncateString(txt, len) {
if (!txt) {
return;
}
if (txt.length > len) {
return txt.slice(0, len-3) + '...';
} else {
return txt;
}
}
function shortenLargeNumber(label) {
let number;
if (typeof label === 'number') number = label;
else if (typeof label === 'string') {
number = Number(label);
if (Number.isNaN(number)) return label;
}
// Using absolute since log wont work for negative numbers
let p = Math.floor(Math.log10(Math.abs(number)));
if (p <= 2) return number; // Return as is for a 3 digit number of less
let l = Math.floor(p / 3);
let 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];
}
const PRESET_COLOR_MAP = { const PRESET_COLOR_MAP = {
'light-blue': '#7cd6fd', 'light-blue': '#7cd6fd',
'blue': '#5e64ff', 'blue': '#5e64ff',
@ -430,6 +459,7 @@ const getColor = (color) => {
const AXIS_TICK_LENGTH = 6; const AXIS_TICK_LENGTH = 6;
const LABEL_MARGIN = 4; const LABEL_MARGIN = 4;
const LABEL_MAX_CHARS = 15;
const FONT_SIZE = 10; const FONT_SIZE = 10;
const BASE_LINE_COLOR = '#dadada'; const BASE_LINE_COLOR = '#dadada';
const FONT_FILL = '#555b51'; const FONT_FILL = '#555b51';
@ -538,12 +568,36 @@ function makeArcPathStr(startPosition, endPosition, center, radius, clockWise=1,
${arcEndX} ${arcEndY} z`; ${arcEndX} ${arcEndY} z`;
} }
function makeArcStrokePathStr(startPosition, endPosition, center, radius, clockWise=1){ function makeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, center.y * 2, center.y + endPosition.y];
return `M${center.x} ${center.y}
L${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${midArc} z
L${arcStartX} ${midArc}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY} z`;
}
function makeArcStrokePathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y]; let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y]; let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y];
return `M${arcStartX} ${arcStartY} return `M${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 0 ${clockWise ? 1 : 0} A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY}`;
}
function makeStrokeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, radius * 2 + arcStartY, center.y + startPosition.y];
return `M${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${midArc}
M${arcStartX} ${midArc}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY}`; ${arcEndX} ${arcEndY}`;
} }
@ -601,7 +655,9 @@ function heatSquare(className, x, y, size, fill='none', data={}) {
return createSVG("rect", args); return createSVG("rect", args);
} }
function legendBar(x, y, size, fill='none', label) { function legendBar(x, y, size, fill='none', label, truncate=false) {
label = truncate ? truncateString(label, LABEL_MAX_CHARS) : label;
let args = { let args = {
className: 'legend-bar', className: 'legend-bar',
x: 0, x: 0,
@ -711,6 +767,8 @@ function makeVertLine(x, label, y1, y2, options={}) {
function makeHoriLine(y, label, x1, x2, options={}) { function makeHoriLine(y, label, x1, x2, options={}) {
if(!options.stroke) options.stroke = BASE_LINE_COLOR; if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.lineType) options.lineType = ''; if(!options.lineType) options.lineType = '';
if (options.shortenNumbers) label = shortenLargeNumber(label);
let className = 'line-horizontal ' + options.className + let className = 'line-horizontal ' + options.className +
(options.lineType === "dashed" ? "dashed": ""); (options.lineType === "dashed" ? "dashed": "");
@ -772,7 +830,8 @@ function yLine(y, label, width, options={}) {
return makeHoriLine(y, label, x1, x2, { return makeHoriLine(y, label, x1, x2, {
stroke: options.stroke, stroke: options.stroke,
className: options.className, className: options.className,
lineType: options.lineType lineType: options.lineType,
shortenNumbers: options.shortenNumbers
}); });
} }
@ -1379,7 +1438,8 @@ class BaseChart {
showTooltip: 1, // calculate showTooltip: 1, // calculate
showLegend: 1, // calculate showLegend: 1, // calculate
isNavigable: options.isNavigable || 0, isNavigable: options.isNavigable || 0,
animate: 1 animate: 1,
truncateLegends: options.truncateLegends || 0
}; };
this.measures = JSON.parse(JSON.stringify(BASE_MEASURES)); this.measures = JSON.parse(JSON.stringify(BASE_MEASURES));
@ -1941,7 +2001,7 @@ let componentConfigs = {
makeElements(data) { makeElements(data) {
return data.positions.map((position, i) => return data.positions.map((position, i) =>
yLine(position, data.labels[i], this.constants.width, yLine(position, data.labels[i], this.constants.width,
{mode: this.constants.mode, pos: this.constants.pos}) {mode: this.constants.mode, pos: this.constants.pos, shortenNumbers: this.constants.shortenNumbers})
); );
}, },
@ -2389,10 +2449,7 @@ class PieChart extends AggregationChart {
s.sliceTotals.map((total, i) => { s.sliceTotals.map((total, i) => {
const startAngle = curAngle; const startAngle = curAngle;
const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE; const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE;
let largeArc = 0; const largeArc = originDiffAngle > 180 ? 1: 0;
if(originDiffAngle > 180){
largeArc = 1;
}
const diffAngle = clockWise ? -originDiffAngle : originDiffAngle; const diffAngle = clockWise ? -originDiffAngle : originDiffAngle;
const endAngle = curAngle = curAngle + diffAngle; const endAngle = curAngle = curAngle + diffAngle;
const startPosition = getPositionByAngle(startAngle, radius); const startPosition = getPositionByAngle(startAngle, radius);
@ -2408,7 +2465,11 @@ class PieChart extends AggregationChart {
curStart = startPosition; curStart = startPosition;
curEnd = endPosition; curEnd = endPosition;
} }
const curPath = makeArcPathStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc); const curPath =
originDiffAngle === 360
? makeCircleStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc)
: makeArcPathStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc);
s.sliceStrings.push(curPath); s.sliceStrings.push(curPath);
s.slicesProperties.push({ s.slicesProperties.push({
startPosition, startPosition,
@ -3161,6 +3222,7 @@ class AxisChart extends BaseChart {
this.config.xAxisMode = options.axisOptions.xAxisMode || 'span'; this.config.xAxisMode = options.axisOptions.xAxisMode || 'span';
this.config.yAxisMode = options.axisOptions.yAxisMode || 'span'; this.config.yAxisMode = options.axisOptions.yAxisMode || 'span';
this.config.xIsSeries = options.axisOptions.xIsSeries || 0; this.config.xIsSeries = options.axisOptions.xIsSeries || 0;
this.config.shortenYAxisNumbers = options.axisOptions.shortenYAxisNumbers || 0;
this.config.formatTooltipX = options.tooltipOptions.formatTooltipX; this.config.formatTooltipX = options.tooltipOptions.formatTooltipX;
this.config.formatTooltipY = options.tooltipOptions.formatTooltipY; this.config.formatTooltipY = options.tooltipOptions.formatTooltipY;
@ -3315,6 +3377,7 @@ class AxisChart extends BaseChart {
{ {
mode: this.config.yAxisMode, mode: this.config.yAxisMode,
width: this.width, width: this.width,
shortenNumbers: this.config.shortenYAxisNumbers
// pos: 'right' // pos: 'right'
}, },
function() { function() {
@ -3552,7 +3615,8 @@ class AxisChart extends BaseChart {
'0', '0',
barWidth, barWidth,
this.colors[i], this.colors[i],
d.name); d.name,
this.config.truncateLegends);
this.legendArea.appendChild(rect); this.legendArea.appendChild(rect);
}); });
} }
@ -3746,6 +3810,7 @@ class DonutChart extends AggregationChart {
s.sliceTotals.map((total, i) => { s.sliceTotals.map((total, i) => {
const startAngle = curAngle; const startAngle = curAngle;
const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE; const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE;
const largeArc = originDiffAngle > 180 ? 1: 0;
const diffAngle = clockWise ? -originDiffAngle : originDiffAngle; const diffAngle = clockWise ? -originDiffAngle : originDiffAngle;
const endAngle = curAngle = curAngle + diffAngle; const endAngle = curAngle = curAngle + diffAngle;
const startPosition = getPositionByAngle(startAngle, radius); const startPosition = getPositionByAngle(startAngle, radius);
@ -3761,7 +3826,10 @@ class DonutChart extends AggregationChart {
curStart = startPosition; curStart = startPosition;
curEnd = endPosition; curEnd = endPosition;
} }
const curPath = makeArcStrokePathStr(curStart, curEnd, this.center, this.radius, this.clockWise); 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.sliceStrings.push(curPath);
s.slicesProperties.push({ s.slicesProperties.push({

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -27,7 +27,8 @@ export default {
colors: ["violet", "light-blue", "#46a9f9"], colors: ["violet", "light-blue", "#46a9f9"],
valuesOverPoints: 1, valuesOverPoints: 1,
axisOptions: { axisOptions: {
xAxisMode: "tick" xAxisMode: "tick",
shortenYAxisNumbers: true
}, },
barOptions: { barOptions: {
stacked: 1 stacked: 1

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -274,7 +274,8 @@ var demoConfig = {
colors: ["violet", "light-blue", "#46a9f9"], colors: ["violet", "light-blue", "#46a9f9"],
valuesOverPoints: 1, valuesOverPoints: 1,
axisOptions: { axisOptions: {
xAxisMode: "tick" xAxisMode: "tick",
shortenYAxisNumbers: true
}, },
barOptions: { barOptions: {
stacked: 1 stacked: 1

File diff suppressed because one or more lines are too long

View File

@ -38,6 +38,7 @@ export default class AxisChart extends BaseChart {
this.config.xAxisMode = options.axisOptions.xAxisMode || 'span'; this.config.xAxisMode = options.axisOptions.xAxisMode || 'span';
this.config.yAxisMode = options.axisOptions.yAxisMode || 'span'; this.config.yAxisMode = options.axisOptions.yAxisMode || 'span';
this.config.xIsSeries = options.axisOptions.xIsSeries || 0; this.config.xIsSeries = options.axisOptions.xIsSeries || 0;
this.config.shortenYAxisNumbers = options.axisOptions.shortenYAxisNumbers || 0;
this.config.formatTooltipX = options.tooltipOptions.formatTooltipX; this.config.formatTooltipX = options.tooltipOptions.formatTooltipX;
this.config.formatTooltipY = options.tooltipOptions.formatTooltipY; this.config.formatTooltipY = options.tooltipOptions.formatTooltipY;
@ -192,6 +193,7 @@ export default class AxisChart extends BaseChart {
{ {
mode: this.config.yAxisMode, mode: this.config.yAxisMode,
width: this.width, width: this.width,
shortenNumbers: this.config.shortenYAxisNumbers
// pos: 'right' // pos: 'right'
}, },
function() { function() {

View File

@ -2,7 +2,7 @@ import AggregationChart from './AggregationChart';
import { getComponent } from '../objects/ChartComponents'; import { getComponent } from '../objects/ChartComponents';
import { getOffset } from '../utils/dom'; import { getOffset } from '../utils/dom';
import { getPositionByAngle } from '../utils/helpers'; import { getPositionByAngle } from '../utils/helpers';
import { makeArcStrokePathStr } from '../utils/draw'; import { makeArcStrokePathStr, makeStrokeCircleStr } from '../utils/draw';
import { lightenDarkenColor } from '../utils/colors'; import { lightenDarkenColor } from '../utils/colors';
import { transform } from '../utils/animation'; import { transform } from '../utils/animation';
import { FULL_ANGLE } from '../utils/constants'; import { FULL_ANGLE } from '../utils/constants';
@ -63,7 +63,10 @@ export default class DonutChart extends AggregationChart {
curStart = startPosition; curStart = startPosition;
curEnd = endPosition; curEnd = endPosition;
} }
const curPath = makeArcStrokePathStr(curStart, curEnd, this.center, this.radius, this.clockWise, largeArc); 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.sliceStrings.push(curPath);
s.slicesProperties.push({ s.slicesProperties.push({

View File

@ -2,7 +2,7 @@ import AggregationChart from './AggregationChart';
import { getComponent } from '../objects/ChartComponents'; import { getComponent } from '../objects/ChartComponents';
import { getOffset } from '../utils/dom'; import { getOffset } from '../utils/dom';
import { getPositionByAngle } from '../utils/helpers'; import { getPositionByAngle } from '../utils/helpers';
import { makeArcPathStr } from '../utils/draw'; import { makeArcPathStr, makeCircleStr } from '../utils/draw';
import { lightenDarkenColor } from '../utils/colors'; import { lightenDarkenColor } from '../utils/colors';
import { transform } from '../utils/animation'; import { transform } from '../utils/animation';
import { FULL_ANGLE } from '../utils/constants'; import { FULL_ANGLE } from '../utils/constants';
@ -58,7 +58,11 @@ export default class PieChart extends AggregationChart {
curStart = startPosition; curStart = startPosition;
curEnd = endPosition; curEnd = endPosition;
} }
const curPath = makeArcPathStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc); const curPath =
originDiffAngle === 360
? makeCircleStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc)
: makeArcPathStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc);
s.sliceStrings.push(curPath); s.sliceStrings.push(curPath);
s.slicesProperties.push({ s.slicesProperties.push({
startPosition, startPosition,

View File

@ -3,7 +3,7 @@ import * as Charts from './chart';
let frappe = { }; let frappe = { };
frappe.NAME = 'Frappe Charts'; frappe.NAME = 'Frappe Charts';
frappe.VERSION = '1.2.0'; frappe.VERSION = '1.2.4';
frappe = Object.assign({ }, frappe, Charts); frappe = Object.assign({ }, frappe, Charts);

View File

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

View File

@ -35,3 +35,21 @@ export function truncateString(txt, len) {
return txt; return txt;
} }
} }
export function shortenLargeNumber(label) {
let number;
if (typeof label === 'number') number = label;
else if (typeof label === 'string') {
number = Number(label);
if (Number.isNaN(number)) return label;
}
// Using absolute since log wont work for negative numbers
let p = Math.floor(Math.log10(Math.abs(number)));
if (p <= 2) return number; // Return as is for a 3 digit number of less
let l = Math.floor(p / 3);
let 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];
}

View File

@ -1,4 +1,4 @@
import { getBarHeightAndYAttr, truncateString } from './draw-utils'; import { getBarHeightAndYAttr, truncateString, shortenLargeNumber } from './draw-utils';
import { getStringWidth } from './helpers'; import { getStringWidth } from './helpers';
import { DOT_OVERLAY_SIZE_INCR, PERCENTAGE_BAR_DEFAULT_DEPTH } from './constants'; import { DOT_OVERLAY_SIZE_INCR, PERCENTAGE_BAR_DEFAULT_DEPTH } from './constants';
import { lightenDarkenColor } from './colors'; import { lightenDarkenColor } from './colors';
@ -120,6 +120,18 @@ export function makeArcPathStr(startPosition, endPosition, center, radius, clock
${arcEndX} ${arcEndY} z`; ${arcEndX} ${arcEndY} z`;
} }
export function makeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, center.y * 2, center.y + endPosition.y];
return `M${center.x} ${center.y}
L${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${midArc} z
L${arcStartX} ${midArc}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY} z`;
}
export function makeArcStrokePathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){ export function makeArcStrokePathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y]; let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y]; let [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y];
@ -129,6 +141,18 @@ export function makeArcStrokePathStr(startPosition, endPosition, center, radius,
${arcEndX} ${arcEndY}`; ${arcEndX} ${arcEndY}`;
} }
export function makeStrokeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){
let [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];
let [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, radius * 2 + arcStartY, center.y + startPosition.y];
return `M${arcStartX} ${arcStartY}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${midArc}
M${arcStartX} ${midArc}
A ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}
${arcEndX} ${arcEndY}`;
}
export function makeGradient(svgDefElem, color, lighter = false) { 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 gradientDef = renderVerticalGradient(svgDefElem, gradientId);
@ -295,6 +319,8 @@ function makeVertLine(x, label, y1, y2, options={}) {
function makeHoriLine(y, label, x1, x2, options={}) { function makeHoriLine(y, label, x1, x2, options={}) {
if(!options.stroke) options.stroke = BASE_LINE_COLOR; if(!options.stroke) options.stroke = BASE_LINE_COLOR;
if(!options.lineType) options.lineType = ''; if(!options.lineType) options.lineType = '';
if (options.shortenNumbers) label = shortenLargeNumber(label);
let className = 'line-horizontal ' + options.className + let className = 'line-horizontal ' + options.className +
(options.lineType === "dashed" ? "dashed": ""); (options.lineType === "dashed" ? "dashed": "");
@ -356,7 +382,8 @@ export function yLine(y, label, width, options={}) {
return makeHoriLine(y, label, x1, x2, { return makeHoriLine(y, label, x1, x2, {
stroke: options.stroke, stroke: options.stroke,
className: options.className, className: options.className,
lineType: options.lineType lineType: options.lineType,
shortenNumbers: options.shortenNumbers
}); });
} }

2867
yarn.lock

File diff suppressed because it is too large Load Diff