UNPKG

dbl-components

Version:

Framework based on bootstrap 5

105 lines (91 loc) 3.03 kB
import { createRef } from "react"; import PropTypes from "prop-types"; import { Doughnut, Bar, Bubble, Chart, Line, Pie, PolarArea, Radar, Scatter } from "react-chartjs-2"; import { eventHandler } from "dbl-utils"; import ProportionalContainer from "../containers/proportional-container"; import Icons from "../media/icons"; const graphs = { Doughnut, Bar, Bubble, Chart, Line, Pie, PolarArea, Radar, Scatter }; export const addGraphs = (moreGraphs) => Object.assign(graphs, moreGraphs); export default class Chartjs extends ProportionalContainer { static jsClass = 'Chartjs'; static propTypes = { ...ProportionalContainer.propTypes, data: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired, ratio: PropTypes.oneOfType([PropTypes.number, PropTypes.objectOf(PropTypes.number)]), options: PropTypes.object, plugins: PropTypes.array, datasetIdKey: PropTypes.string, fallbackContent: PropTypes.node, updateMode: PropTypes.oneOf([ 'active', 'hide', 'none', 'normal', 'reset', 'resize', 'show' ]), graph: PropTypes.string }; static defaultProps = { ...ProportionalContainer.defaultProps, ratio: 1, options: {}, plugins: [], datasetIdKey: 'label', fallbackContent: null, graph: 'Bar' } events = []; constructor(props) { super(props); this.refChart = createRef(); this.events.push( ['ready.' + this.props.name, this.onReadyElement.bind(this)], ['resize.' + this.props.name, this.onResizeElement.bind(this)] ); Object.assign(this.state, { }); } componentDidMount() { this.events.forEach(([e, cb]) => eventHandler.subscribe(e, cb, this.name)); super.componentDidMount(); } componentWillUnmount() { super.componentWillUnmount(); this.events.forEach(([e]) => eventHandler.unsubscribe(e, this.name)); clearTimeout(this.timeoutUpdate); } onReadyElement(obj) { } onResizeElement(resize) { if (this.refChart.current) this.refChart.current.update(); } content(children = this.props.children) { const options = { ...this.props.options }; options.aspectRatio = 1 / (typeof ratio === 'object' ? this.props.ratio[this.breakpoint] : this.props.ratio); const attribs = { data: this.props.data, options, plugins: this.props.plugins, redraw: false, datasetIdKey: this.props.datasetIdKey, fallbackContent: this.props.fallbackContent, updateMode: this.props.updateMode, ref: (ref) => { this.refChart.current = ref; if (this.props.ref) this.props.ref.current = ref; } } const Graph = graphs[this.props.graph]; const proportional = super.content(<> {!this.props.loading ? <Graph {...attribs} /> : <Icons icon="spinner" classes="spinner" /> } {children} </> ); return proportional; } }