UNPKG

d2-ui

Version:
156 lines (138 loc) 4.87 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Popover from 'material-ui/Popover/Popover'; import SelectField from 'material-ui/SelectField/SelectField'; import MenuItem from 'material-ui/MenuItem/MenuItem'; import { config } from 'd2/lib/d2'; import ColorScale from './ColorScale.component'; import colorbrewer from './colorbrewer'; import Row from '../layout/Row.component'; import Column from '../layout/Column.component'; config.i18n.strings.add('number_of_items'); // Allowed color scales from ColorBrewer (needs to have at least 9 classes) const scales = [ 'YlOrRd', 'Reds', 'YlGn', 'Greens', 'Blues', 'BuPu', 'RdPu', 'PuRd', 'Greys', 'YlOrBr_reverse', 'Reds_reverse', 'YlGn_reverse', 'Greens_reverse', 'Blues_reverse', 'BuPu_reverse', 'RdPu_reverse', 'PuRd_reverse', 'Greys_reverse', 'PuOr', 'BrBG', 'PRGn', 'PiYG', 'RdBu', 'RdGy', 'RdYlBu', 'Spectral', 'RdYlGn', 'Paired', 'Pastel1', 'Set1', 'Set3', ]; // Renders a color scale component consisting of a changeable color scale and number of classes class ColorScaleSelect extends Component { constructor(...args) { super(...args); this.state = { open: false, anchorEl: null, scale: 'YlOrRd', classes: 5, }; this.i18n = this.context.d2.i18n; } componentDidMount() { this.props.onChange(this.getColorBrewerScale(this.state.scale, this.state.classes)); } // Show popover with allowed color scales showColorScales = (event) => { this.setState({ open: true, anchorEl: event.currentTarget }); } // Called when a new color scale is selected in the popover onColorScaleSelect = (event, scale) => { this.setState({ scale, open: false }); this.props.onChange(this.getColorBrewerScale(scale, this.state.classes)); } // Called when the number of classes is changed onClassesChange = (event, index, value) => { this.setState({ classes: value }); this.props.onChange(this.getColorBrewerScale(this.state.scale, value)); } // Returns a color brewer scale for a number of classes getColorBrewerScale(scale, classes) { return colorbrewer[scale][classes]; } // Called when popover is closed onColorScalePopoverClose = () => { this.setState({ open: false }); } render() { const styles = { scale: { width: 36 * this.state.classes, minWidth: 36 * this.state.classes, flex: '0 0 auto', }, popover: { maxHeight: '60%', overflowY: 'scroll', }, popoverScale: { display: 'block', overflow: 'visible', margin: '10px 0', marginLeft: 20, width: 36 * this.state.classes, minWidth: 36 * this.state.classes, whiteSpace: 'nowrap', }, }; const colorScales = scales.map((scale, index) => <ColorScale key={index} scale={scale} classes={this.state.classes} style={styles.popoverScale} onClick={this.onColorScaleSelect} />, ); return ( <Row style={{ alignItems: 'center', ...this.props.style }}> <SelectField floatingLabelText={this.i18n.getTranslation('number_of_items')} value={this.state.classes} onChange={this.onClassesChange}> <MenuItem value={3} primaryText="3" /> <MenuItem value={4} primaryText="4" /> <MenuItem value={5} primaryText="5" /> <MenuItem value={6} primaryText="6" /> <MenuItem value={7} primaryText="7" /> <MenuItem value={8} primaryText="8" /> <MenuItem value={9} primaryText="9" /> </SelectField> <ColorScale scale={this.state.scale} classes={this.state.classes} style={{ ...styles.scale, margin: '0 20px 0 20px' }} onClick={this.showColorScales} /> <Popover style={styles.popover} open={this.state.open} anchorEl={this.state.anchorEl} anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }} targetOrigin={{ horizontal: 'left', vertical: 'top' }} onRequestClose={this.onColorScalePopoverClose} > <Column> {colorScales} </Column> </Popover> </Row> ); } } ColorScaleSelect.contextTypes = { d2: PropTypes.object, }; export default ColorScaleSelect;