ice-frontend-react-mobx
Version:
ICE Frontend REACT+MobX
123 lines (102 loc) • 4.36 kB
JavaScript
var debug = require('debug')('ice:DonutGraphPureJS'); // eslint-disable-line no-unused-vars
import { inject, observer } from 'mobx-react';
import React from 'react';
const styles = require('./DonutGraphPureJS.css');
const defaultState = {
phaseData: [],
thickness: 10,
styleName: styles.graphWrapper
};
let parentEl = null;
@inject('store') @observer
class DonutGraphPureJS extends React.Component {
createChart (params) {
var namespace = 'http://www.w3.org/2000/svg';
// Measures the container, sets pie radius to a maximum value that would fit in the container
var getComputedPadding = function (element, css) {
return parseInt(window.getComputedStyle(params.parent)['padding-' + css]);
};
params.width = params.width || (params.parent.clientWidth - getComputedPadding(params.parent, 'left') - getComputedPadding(params.parent, 'right'));
params.height = params.height || (params.parent.clientHeight - getComputedPadding(params.parent, 'top') - getComputedPadding(params.parent, 'bottom'));
params.radius = params.width >= params.height ? params.height / 2 : params.width / 2;
params.adjustedRadius = params.radius - (params.borderWidth / 2);
// Creates a pie chart
var chart = params.parent.querySelector('svg.pieChart') || document.createElementNS(namespace, 'svg');
chart.setAttribute('class', 'pieChart');
chart.setAttribute('width', params.width);
chart.setAttribute('height', params.height);
params.parent.appendChild(chart);
Array.prototype.slice.call(chart.childNodes).forEach(function (child) {
child.parentNode.removeChild(child);
});
var circumference = params.adjustedRadius * Math.PI * 2;
// Sorts the values
var compare = function (a, b) {
if (a.value < b.value) {
return (params.sortValues === 'asc' ? -1 : 1);
}
if (a.value > b.value) {
return (params.sortValues === 'asc' ? 1 : -1);
}
return 0;
};
if (params.sortValues === 'asc' || params.sortValues === 'desc') {
params.values.sort(compare);
}
// Sums all the values for further calculations
var sum = 0;
params.values.forEach(function (value) {
sum += value.value;
});
// Creates pie chart elements
var chartDrawingPoint = 0;
params.values.forEach(function (value) {
var element = document.createElementNS(namespace, 'circle');
chart.appendChild(element);
var percentage = value.value / sum;
element.setAttribute('r', params.adjustedRadius);
element.setAttribute('cx', '50%');
element.setAttribute('cy', '50%');
element.setAttribute('fill', 'none');
element.setAttribute('stroke', value.color);
element.setAttribute('stroke-width', params.borderWidth);
element.setAttribute('transform', 'rotate(90, ' + (params.width / 2) + ', ' + (params.height / 2) + ')');
element.setAttribute(
'stroke-dasharray',
'0, ' + /* no value here, ever */
chartDrawingPoint + ', ' + /* empty space before pie chart element */
percentage * circumference + ', ' + /* actual stroke */
circumference /* empty space after pie chart element */
);
chartDrawingPoint += percentage * circumference;
});
};
componentWillReceiveProps (nextProps) {
let newState = Object.assign({}, defaultState);
newState.phaseData = nextProps.phaseData || defaultState.phaseData;
newState.thickness = nextProps.thickness || defaultState.thickness;
newState.styleName = nextProps.styleName || defaultState.styleName;
this.setState(newState);
};
componentDidMount () {
parentEl = document.getElementById('rel');
};
render () {
let _phaseData = this.state ? this.state.phaseData : defaultState.phaseData;
let _thickness = this.state ? this.state.thickness : defaultState.thickness;
let _styleName = this.state ? this.state.styleName : defaultState.styleName;
if (parentEl) {
this.createChart({
parent: parentEl,
borderWidth: _thickness,
sortValues: 'desc',
values: _phaseData
});
};
// Currently supports phase data. Can be extended as need arises. Also - Is only drawn if feed is 3 phase.
return (
<div id='rel' className={_styleName}></div>
);
}
}
export default DonutGraphPureJS;