UNPKG

ice-frontend-react-mobx

Version:
123 lines (102 loc) 4.36 kB
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;