Browse Source

setup Pie chart component slices

tags/1.2.0
Prateeksha Singh 7 years ago
parent
commit
ded80791dd
15 changed files with 1068 additions and 993 deletions
  1. +938
    -901
      dist/frappe-charts.esm.js
  2. +1
    -1
      dist/frappe-charts.min.cjs.js
  3. +1
    -1
      dist/frappe-charts.min.esm.js
  4. +1
    -1
      dist/frappe-charts.min.iife.js
  5. +1
    -1
      dist/frappe-charts.min.iife.js.map
  6. +1
    -1
      docs/assets/js/frappe-charts.min.js
  7. +1
    -1
      docs/assets/js/frappe-charts.min.js.map
  8. +0
    -4
      src/js/charts/AggregationChart.js
  9. +0
    -11
      src/js/charts/AxisChart.js
  10. +3
    -1
      src/js/charts/BaseChart.js
  11. +10
    -10
      src/js/charts/PercentageChart.js
  12. +84
    -54
      src/js/charts/PieChart.js
  13. +19
    -2
      src/js/objects/ChartComponents.js
  14. +4
    -0
      src/js/utils/animate.js
  15. +4
    -4
      src/js/utils/draw-utils.js

+ 938
- 901
dist/frappe-charts.esm.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/frappe-charts.min.cjs.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/frappe-charts.min.esm.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/frappe-charts.min.iife.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/frappe-charts.min.iife.js.map
File diff suppressed because it is too large
View File


+ 1
- 1
docs/assets/js/frappe-charts.min.js
File diff suppressed because it is too large
View File


+ 1
- 1
docs/assets/js/frappe-charts.min.js.map
File diff suppressed because it is too large
View File


+ 0
- 4
src/js/charts/AggregationChart.js View File

@@ -47,10 +47,6 @@ export default class AggregationChart extends BaseChart {
});
}

render() { }

bindTooltip() { }

renderLegend() {
let s = this.state;



+ 0
- 11
src/js/charts/AxisChart.js View File

@@ -215,8 +215,6 @@ export default class AxisChart extends BaseChart {
let barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');
let lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');

// console.log('barDatasets', barDatasets, this.state.datasets);

let barsConfigs = barDatasets.map(d => {
let index = d.index;
return [
@@ -480,12 +478,10 @@ export default class AxisChart extends BaseChart {

addDataPoint(label, datasetValues, index=this.state.datasetLength) {
super.addDataPoint(label, datasetValues, index);
// console.log(label, datasetValues, this.data.labels);
this.data.labels.splice(index, 0, label);
this.data.datasets.map((d, i) => {
d.values.splice(index, 0, datasetValues[i]);
});
// console.log(this.data);
this.update(this.data);
}

@@ -498,9 +494,6 @@ export default class AxisChart extends BaseChart {
this.update(this.data);
}

// getDataPoint(index = 0) {}
// setCurrentDataPoint(point) {}

updateDataset(datasetValues, index=0) {
this.data.datasets[index].values = datasetValues;
this.update(this.data);
@@ -514,7 +507,3 @@ export default class AxisChart extends BaseChart {
// addDataPoint(dataPoint, index = 0) {}
// removeDataPoint(index = 0) {}
}


// keep a binding at the end of chart


+ 3
- 1
src/js/charts/BaseChart.js View File

@@ -34,6 +34,8 @@ export default class BaseChart {
this.state = {};
this.options = {};

this.initTimeout = INIT_CHART_UPDATE_TIMEOUT;

if(this.config.isNavigable) {
this.overlays = [];
}
@@ -138,7 +140,7 @@ export default class BaseChart {

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

this.renderLegend();


+ 10
- 10
src/js/charts/PercentageChart.js View File

@@ -35,8 +35,8 @@ export default class PercentageChart extends AggregationChart {

render() {
let s = this.state;
this.grand_total = s.sliceTotals.reduce((a, b) => a + b, 0);
this.slices = [];
this.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0);
s.slices = [];
s.sliceTotals.map((total, i) => {
let slice = $.create('div', {
className: `progress-bar`,
@@ -44,10 +44,10 @@ export default class PercentageChart extends AggregationChart {
inside: this.percentageBar,
styles: {
background: this.colors[i],
width: total*100/this.grand_total + "%"
width: total*100/this.grandTotal + "%"
}
});
this.slices.push(slice);
s.slices.push(slice);
});
}

@@ -59,13 +59,13 @@ export default class PercentageChart extends AggregationChart {
if(slice.classList.contains('progress-bar')) {

let i = slice.getAttribute('data-index');
let g_off = getOffset(this.chartWrapper), p_off = getOffset(slice);
let gOff = getOffset(this.chartWrapper), pOff = getOffset(slice);

let x = p_off.left - g_off.left + slice.offsetWidth/2;
let y = p_off.top - g_off.top - 6;
let title = (this.formatted_labels && this.formatted_labels.length>0
? this.formatted_labels[i] : this.state.labels[i]) + ': ';
let percent = (s.sliceTotals[i]*100/this.grand_total).toFixed(1);
let x = pOff.left - gOff.left + slice.offsetWidth/2;
let y = pOff.top - gOff.top - 6;
let title = (this.formattedLabels && this.formattedLabels.length>0
? this.formattedLabels[i] : this.state.labels[i]) + ': ';
let percent = (s.sliceTotals[i]*100/this.grandTotal).toFixed(1);

this.tip.setValues(x, y, title, percent + "%");
this.tip.showTip();


+ 84
- 54
src/js/charts/PieChart.js View File

@@ -1,5 +1,6 @@
import AggregationChart from './AggregationChart';
import { $, getOffset } from '../utils/dom';
import { getComponent } from '../objects/ChartComponents';
import { getOffset } from '../utils/dom';
import { getPositionByAngle } from '../utils/helpers';
import { makePath, makeArcPathStr } from '../utils/draw';
import { lightenDarkenColor } from '../utils/colors';
@@ -10,10 +11,7 @@ export default class PieChart extends AggregationChart {
constructor(parent, args) {
super(parent, args);
this.type = 'pie';

this.hoverRadio = args.hoverRadio || 0.1;
this.startAngle = args.startAngle || 0;
this.clockWise = args.clockWise || false;
this.initTimeout = 0;

this.setup();
}
@@ -22,68 +20,98 @@ export default class PieChart extends AggregationChart {
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.clockWise = args.clockWise || false;
}

prepareFirstData(data=this.data) {
this.init = 1;
return data;
}

calc() {
super.calc();
let s = this.state;

this.center = {
x: this.width / 2,
y: this.height / 2
}
this.radius = (this.height > this.width ? this.center.x : this.center.y);

s.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0);

this.calcSlices();
}

render(init) {
const{radius,clockWise} = this;
this.grand_total = this.state.sliceTotals.reduce((a, b) => a + b, 0);
const prevSlicesProperties = this.slicesProperties || [];
this.slices = [];
this.elements_to_animate = [];
this.slicesProperties = [];
let curAngle = 180 - this.startAngle;
calcSlices() {
let s = this.state;
const { radius, clockWise } = this;
const prevSlicesProperties = s.slicesProperties || [];
s.sliceStrings = [];
s.slicesProperties = [];
let curAngle = 180 - this.config.startAngle;

this.state.sliceTotals.map((total, i) => {
s.sliceTotals.map((total, i) => {
const startAngle = curAngle;
const originDiffAngle = (total / this.grand_total) * FULL_ANGLE;
const originDiffAngle = (total / s.grandTotal) * FULL_ANGLE;
const diffAngle = clockWise ? -originDiffAngle : originDiffAngle;
const endAngle = curAngle = curAngle + diffAngle;
const startPosition = getPositionByAngle(startAngle, radius);
const endPosition = getPositionByAngle(endAngle, radius);
const prevProperty = init && prevSlicesProperties[i];

const prevProperty = this.init && prevSlicesProperties[i];

let curStart,curEnd;
if(init){
curStart = prevProperty?prevProperty.startPosition : startPosition;
curEnd = prevProperty? prevProperty.endPosition : startPosition;
}else{
if(this.init) {
curStart = prevProperty ? prevProperty.startPosition : startPosition;
curEnd = prevProperty ? prevProperty.endPosition : startPosition;
} else {
curStart = startPosition;
curEnd = endPosition;
}
const curPath = makeArcPathStr(curStart, curEnd, this.center, this.radius, this.clockWise);
let slice = makePath(curPath, 'pie-path', 'none', this.colors[i]);
slice.style.transition = 'transform .3s;';
this.drawArea.appendChild(slice);

this.slices.push(slice);
this.slicesProperties.push({
s.sliceStrings.push(curPath);
s.slicesProperties.push({
startPosition,
endPosition,
value: total,
total: this.grand_total,
total: s.grandTotal,
startAngle,
endAngle,
angle: diffAngle
});
if(init){
this.elements_to_animate.push([slice,
{d: makeArcPathStr(startPosition, endPosition, this.center, this.radius, this.clockWise)},
650, "easein",null,{
d:curPath
}]);
}

});
// if(init){
// runSMILAnimation(this.chartWrapper, this.svg, this.elements_to_animate);
// }
this.init = 0;
}

setupComponents() {
let s = this.state;

let componentConfigs = [
[
'pieSlices',
{ },
function() {
return {
sliceStrings: s.sliceStrings,
colors: this.colors
}
}.bind(this)
]
];

this.components = new Map(componentConfigs
.map(args => {
let component = getComponent(...args);
return [args[0], component];
}));
}

calTranslateByAngle(property){
@@ -96,43 +124,45 @@ export default class PieChart extends AggregationChart {
if(!path) return;
const color = this.colors[i];
if(flag) {

transform(path, this.calTranslateByAngle(this.slicesProperties[i]));
transform(path, this.calTranslateByAngle(this.state.slicesProperties[i]));
path.style.fill = 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.grand_total).toFixed(1);
this.tip.set_values(x, y, title, percent + "%");
this.tip.show_tip();
let percent = (this.state.sliceTotals[i] * 100 / this.state.grandTotal).toFixed(1);
this.tip.setValues(x, y, title, percent + "%");
this.tip.showTip();
} else {
transform(path,'translate3d(0,0,0)');
this.tip.hide_tip();
this.tip.hideTip();
path.style.fill = color;
}
}

bindTooltip() {
this.chartWrapper.addEventListener('mousemove', this.mouseMove);
this.chartWrapper.addEventListener('mouseleave', this.mouseLeave);
}

mouseMove(e){
const target = e.target;
let slices = this.components.get('pieSlices').store;
let prevIndex = this.curActiveSliceIndex;
let prevAcitve = this.curActiveSlice;
for(let i = 0; i < this.slices.length; i++){
if(target === this.slices[i]){
this.hoverSlice(prevAcitve,prevIndex,false);
this.curActiveSlice = target;
this.curActiveSliceIndex = i;
this.hoverSlice(target,i,true,e);
break;
}
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);
}
bindTooltip() {
// this.drawArea.addEventListener('mousemove',this.mouseMove);
// this.drawArea.addEventListener('mouseleave',this.mouseLeave);
}
}

+ 19
- 2
src/js/objects/ChartComponents.js View File

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

class ChartComponent {
constructor({
@@ -63,6 +64,22 @@ class ChartComponent {
}

let componentConfigs = {
pieSlices: {
layerClass: 'pie-slices',
makeElements(data) {
return data.sliceStrings.map((s, i) =>{
let slice = makePath(s, 'pie-path', 'none', data.colors[i]);
slice.style.transition = 'transform .3s;';
return slice;
});
},

animateElements(newData) {
return this.store.map((slice, i) =>
animatePathStr(slice, newData.sliceStrings[i])
);
}
},
yAxis: {
layerClass: 'y axis',
makeElements(data) {


+ 4
- 0
src/js/utils/animate.js View File

@@ -99,3 +99,7 @@ export function animatePath(paths, newXList, newYList, zeroLine) {
return pathComponents;
}

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


+ 4
- 4
src/js/utils/draw-utils.js View File

@@ -14,13 +14,13 @@ export function getBarHeightAndYAttr(yTop, zeroLine) {
}

export function equilizeNoOfElements(array1, array2,
extra_count=array2.length - array1.length) {
extraCount = array2.length - array1.length) {

// Doesn't work if either has zero elements.
if(extra_count > 0) {
array1 = fillArray(array1, extra_count);
if(extraCount > 0) {
array1 = fillArray(array1, extraCount);
} else {
array2 = fillArray(array2, extra_count);
array2 = fillArray(array2, extraCount);
}
return [array1, array2];
}

Loading…
Cancel
Save