Pārlūkot izejas kodu

feat: kick start funnel Chart

funnel-chart
Shivam Mishra pirms 5 gadiem
vecāks
revīzija
edf6077eb4
2 mainītis faili ar 117 papildinājumiem un 0 dzēšanām
  1. +91
    -0
      src/js/charts/FunnelChart.js
  2. +26
    -0
      src/js/utils/draw.js

+ 91
- 0
src/js/charts/FunnelChart.js Parādīt failu

@@ -0,0 +1,91 @@
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';

export default class FunnelChart extends AggregationChart {
constructor(parent, args) {
super(parent, args);
this.type = 'funnel';
this.setup();
}

setMeasures(options) {
let m = this.measures;
this.funnelOptions = options.funnelOptions || {};

let opts = this.funnelOptions;
opts.height = opts.height || PERCENTAGE_BAR_DEFAULT_HEIGHT;

m.paddings.right = 30;
m.legendHeight = 60;
m.baseHeight = (opts.height + opts.depth * 0.5) * 8;
}

setupComponents() {
let s = this.state;

let componentConfigs = [
[
'percentageBars',
{
barHeight: this.funnelOptions.height,
barDepth: this.funnelOptions.depth,
},
function() {
return {
xPositions: s.xPositions,
widths: s.widths,
colors: this.colors
};
}.bind(this)
]
];

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

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

s.xPositions = [];
s.widths = [];

let xPos = 0;
s.sliceTotals.map((value) => {
let width = this.width * value / s.grandTotal;
s.widths.push(width);
s.xPositions.push(xPos);
xPos += width;
});
}

makeDataByIndex() { }

bindTooltip() {
let s = this.state;
this.container.addEventListener('mousemove', (e) => {
let bars = this.components.get('percentageBars').store;
let bar = e.target;
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 y = pOff.top - gOff.top;
let title = (this.formattedLabels && this.formattedLabels.length>0
? this.formattedLabels[i] : this.state.labels[i]) + ': ';
let fraction = s.sliceTotals[i]/s.grandTotal;

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

+ 26
- 0
src/js/utils/draw.js Parādīt failu

@@ -190,6 +190,32 @@ export function percentageBar(x, y, width, height,
return createSVG("rect", args);
}

export function funnelSlice(className, startPositions, height, fill='none') {
const endPosition = []
let [point_a, point_b] = startPositions[0]

// For an equilateral triangle, the angles are always 60 deg.
// The end points on the polygons can be created using the following formula
//
// end_point_x = start_x + height
// end_point_y = start_y +/- height * 1/2
//
// b
// _______________________________
// \ |_| /
// \ | /
// \ | h /
// \ | /
// \|____________________/
//
// b = h * cos(60 deg)
//

endPosition[0] = [point_a[0] + height, point_a[1] + height * 0.5]
endPosition[1] = [point_b[0] + height, point_b[1] - height * 0.5]

}

export function heatSquare(className, x, y, size, fill='none', data={}) {
let args = {
className: className,


Notiek ielāde…
Atcelt
Saglabāt