Skip to content

Commit

Permalink
catch up with getredash#2080
Browse files Browse the repository at this point in the history
  • Loading branch information
Allen Short committed Nov 14, 2018
1 parent a7f3ed0 commit 0f57bd3
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 26 deletions.
20 changes: 4 additions & 16 deletions client/app/visualizations/chart/ChartColorEditor.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import Select from 'antd/lib/select';
import 'antd/lib/select/style';
import { map } from 'lodash';

import { ColorPalette } from '@/visualizations/chart/plotly/utils';
import { SeriesOptions, ValuesOptions } from '@/components/proptypes';

const colors = { Automatic: null, ...ColorPalette };
import ColorSelect from './ColorSelect';

export default class ChartColorEditor extends React.Component {
static propTypes = {
Expand All @@ -26,11 +22,6 @@ export default class ChartColorEditor extends React.Component {
changeColor = (value, color) => this.updateOptions(value, { color });

render() {
const colorSelectItem = v => (<span style={{
width: 12, height: 12, backgroundColor: v, display: 'inline-block', marginRight: 5,
}}
/>);
const colorOptionItem = (v, k) => <span style={{ textTransform: 'capitalize' }}>{colorSelectItem(v)}{k}</span>;
return (
<div className="m-t-10 m-b-10">
<table className="table table-condensed col-table">
Expand All @@ -41,13 +32,10 @@ export default class ChartColorEditor extends React.Component {
<div>{name}</div>
</td>
<td style={{ padding: 3, width: 35 }}>
<Select
defaultActiveFirstOption
value={this.props.options[name].color || 'Automatic'}
<ColorSelect
value={this.props.options[name].color}
onChange={selection => this.changeColor(name, selection)}
>
{map(colors, (v, k) => <Select.Option key={v}>{colorOptionItem(v, k)}</Select.Option>)}
</Select>
/>
</td>
</tr>
))}
Expand Down
109 changes: 100 additions & 9 deletions client/app/visualizations/chart/ChartEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { QueryData } from '@/components/proptypes';
import ChartTypePicker from './ChartTypePicker';
import ChartSeriesEditor from './ChartSeriesEditor';
import ChartColorEditor from './ChartColorEditor';
import ColorSelect from './ColorSelect';
import ChartRenderer from './ChartRenderer';

const DEFAULT_CUSTOM_CODE = `// Available variables are x, ys, element, and Plotly
Expand Down Expand Up @@ -49,6 +50,10 @@ function PopoverHelp(props) {

PopoverHelp.propTypes = { children: PropTypes.arrayOf(PropTypes.node).isRequired };

const colorSchemes = ['Blackbody', 'Bluered', 'Blues', 'Earth', 'Electric',
'Greens', 'Greys', 'Hot', 'Jet', 'Picnic', 'Portland',
'Rainbow', 'RdBu', 'Reds', 'Viridis', 'YlGnBu', 'YlOrRd', 'Custom...'];

export default class ChartEditor extends React.Component {
static propTypes = {
data: QueryData.isRequired,
Expand Down Expand Up @@ -117,6 +122,7 @@ export default class ChartEditor extends React.Component {
getErrorColumn = () => findKey(this.props.options.columnMapping, c => c === 'yError')
getSizeColumn = () => findKey(this.props.options.columnMapping, c => c === 'size')
getGroupby = () => findKey(this.props.options.columnMapping, c => c === 'groupby')
getZValue = () => findKey(this.props.options.columnMapping, c => c === 'zVal')

updateOptions = (newOptions) => {
const opts = this.props.options;
Expand Down Expand Up @@ -174,6 +180,9 @@ export default class ChartEditor extends React.Component {
})

toggleSortX = e => this.updateOptions({ sortX: e.target.checked })
toggleReverseX = e => this.updateOptions({ reverseX: e.target.checked })
toggleSortY = e => this.updateOptions({ sortY: e.target.checked })
toggleReverseY = e => this.updateOptions({ reverseY: e.target.checked })

toggleXLabels = e => this.updateOptions({
xAxis: {
Expand All @@ -195,6 +204,7 @@ export default class ChartEditor extends React.Component {
updateGroupby = groupby => this.updateColumn({ groupby })
updateSizeColumn = size => this.updateColumn({ size })
updateErrorColumn = yError => this.updateColumn({ yError })
updateZValue = zVal => this.updateColumn({ zVal })
updateStacking = stacking => this.updateOptions({
series: { ...this.props.options.series, stacking },
})
Expand All @@ -221,6 +231,7 @@ export default class ChartEditor extends React.Component {
updatePercentFormat = e => this.updateOptions({ percentFormat: e.target.value })
updateDateTimeFormat = e => this.updateOptions({ dateTImeFormat: e.target.value })
updateTextFormat = e => this.updateOptions({ textFormat: e.target.value })
updateColorScheme = colorScheme => this.updateOptions({ colorScheme })
yAxisPanel = (side, i) => {
const yAxis = this.props.options.yAxis[i];
return (
Expand Down Expand Up @@ -299,13 +310,14 @@ export default class ChartEditor extends React.Component {
</Select>
</div>

{opts.globalSeriesType !== 'custom' ?
{!includes(['custom', 'heatmap'], opts.globalSeriesType) ?
<div className="form-group">
<label className="control-label">Group by</label>
<Select
placeholder="Choose column..."
value={this.getGroupby()}
onChange={this.updateGroupby}
allowClear
>
{this.groupbyOptions()}
</Select>
Expand All @@ -318,24 +330,37 @@ export default class ChartEditor extends React.Component {
placeholder="Choose column..."
value={this.getSizeColumn()}
onChange={this.updateSizeColumn}
allowClear
>
{this.sizeColumnOptions()}
</Select>
</div> : '' }

{opts.globalSeriesType !== 'custom' ?
</div> : null }
{some(opts.seriesOptions, { type: 'heatmap' }) ?
<div className="form-group">
<label className="control-label">Color Column</label>
<Select
placeholder="Choose column..."
value={this.getZValue()}
onChange={this.updateZValue}
allowClear
>
{this.sizeColumnOptions()}
</Select>
</div> : null }
{!includes(['custom', 'heatmap'], opts.globalSeriesType) ?
<div className="form-group">
<label className="control-label">Errors column</label>
<Select
placeholder="Choose column..."
value={this.getErrorColumn()}
onChange={this.updateErrorColumn}
allowClear
>
{this.xAxisOptions()}
</Select>
</div> : ''}
</div> : null}

{opts.globalSeriesType === 'custom' ?
{!includes(['custom', 'heatmap'], opts.globalSeriesType) ?
<div className="checkbox">
<label>
<input
Expand All @@ -359,7 +384,7 @@ export default class ChartEditor extends React.Component {
</label>
</div> : ''}

{opts.globalSeriesType !== 'custom' ?
{!includes(['custom', 'heatmap'], opts.globalSeriesType) ?
<div className="form-group">
<label className="control-label">Stacking</label>
<Select
Expand Down Expand Up @@ -449,7 +474,16 @@ export default class ChartEditor extends React.Component {
<i className="input-helper" /> Sort Values
</label>
</div>

<div className="checkbox">
<label>
<input
type="checkbox"
onChange={this.toggleReverseX}
checked={opts.reverseX}
/>
<i className="input-helper" /> Reverse Order
</label>
</div>
<div className="checkbox">
<label>
<input
Expand All @@ -473,6 +507,27 @@ export default class ChartEditor extends React.Component {
<div className="m-t-10 m-b-10">
{this.yAxisPanel('Left', 0)}
{this.yAxisPanel('Right', 1)}
<div className="checkbox">
<label>
<input
type="checkbox"
onChange={this.toggleSortY}
checked={opts.sortY}
/>
<i className="input-helper" /> Sort Values
</label>
</div>
<div className="checkbox">
<label>
<input
type="checkbox"
onChange={this.toggleReverseY}
checked={opts.reverseY}
/>
<i className="input-helper" /> Reverse Order
</label>
</div>

</div>
</Tabs.TabPane> : null }
{opts.globalSeriesType !== 'custom' ?
Expand All @@ -486,7 +541,43 @@ export default class ChartEditor extends React.Component {
clientConfig={this.props.clientConfig}
/>
</Tabs.TabPane> : null }
{opts.globalSeriesType !== 'custom' ?
{opts.globalSeriesType === 'heatmap' ?
<Tabs.TabPane key="colors" tab="Colors">
<div className="form-group">
<label className="control-label">Color Scheme</label>
<Select
value={opts.colorScheme}
placeholder="Choose color scheme..."
onChange={this.updateColorScheme}
allowClear
>
{map(colorSchemes, c => <Select.Option key={c}>{c}</Select.Option>)}
</Select>
</div>
<div className="row">
<div className="col-xs-6">
{opts.colorScheme === 'Custom...' ?
<div className="form-group">
<label className="control-label">Min Color</label>
<ColorSelect
value={opts.heatMinColor}
onChange={this.updateHeatMinColor}
/>
</div> : null }
</div>
<div className="col-xs-6">
{opts.colorScheme === 'Custom...' ?
<div className="form-group">
<label className="control-label">Max Color</label>
<ColorSelect
value={opts.heatMaxColor}
onChange={this.updateHeatMaxColor}
/>
</div> : null }
</div>
</div>
</Tabs.TabPane> : null }
{!includes(['custom', 'heatmap'], opts.globalSeriesType) ?
<Tabs.TabPane key="colors" tab="Colors">
<ChartColorEditor
list={pie ? valuesList : seriesList}
Expand Down
9 changes: 9 additions & 0 deletions client/app/visualizations/chart/ChartRenderer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ function chartData(mapping, data) {
const yValues = {};
let eValue = null;
let sizeValue = null;
let zValue = null;

each(row, (v, definition) => {
definition = '' + definition;
Expand Down Expand Up @@ -68,6 +69,11 @@ function chartData(mapping, data) {
sizeValue = value;
}

if (type === 'zVal') {
point[type] = value;
zValue = value;
}

if (type === 'multiFilter' || type === 'multi-filter') {
seriesName = String(value);
}
Expand All @@ -83,6 +89,9 @@ function chartData(mapping, data) {
if (sizeValue !== null) {
point.size = sizeValue;
}
if (zValue !== null) {
point.zVal = zValue;
}
addPointToSeries(point, series, ySeriesName);
});
} else {
Expand Down
1 change: 1 addition & 0 deletions client/app/visualizations/chart/ChartTypePicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const chartTypes = [
{ value: 'pie', label: 'Pie', icon: 'pie-chart' },
{ value: 'scatter', label: 'Scatter', icon: 'circle-o' },
{ value: 'bubble', label: 'Bubble', icon: 'circle-o' },
{ value: 'heatmap', label: 'Heatmap', icon: 'th' },
{ value: 'box', label: 'Box', icon: 'square-o' },
];

Expand Down
38 changes: 38 additions & 0 deletions client/app/visualizations/chart/ColorSelect.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import PropTypes from 'prop-types';
import Select from 'antd/lib/select';
import 'antd/lib/select/style';
import { map } from 'lodash';

import { ColorPalette } from '@/visualizations/chart/plotly/utils';


const colors = { Automatic: null, ...ColorPalette };
const colorSelectItem = v => (
<span
style={{
width: 12,
height: 12,
backgroundColor: v,
display: 'inline-block',
marginRight: 5,
}}
/>);
const colorOptionItem = (v, k) => <span style={{ textTransform: 'capitalize' }}>{colorSelectItem(v)}{k}</span>;


export default function ColorSelect(props) {
return (
<Select
defaultActiveFirstOption
value={props.value || 'Automatic'}
onChange={props.onChange}
>
{map(colors, (v, k) => <Select.Option key={v}>{colorOptionItem(v, k)}</Select.Option>)}
</Select>);
}

ColorSelect.propTypes = {
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
};
4 changes: 3 additions & 1 deletion client/app/visualizations/chart/PlotlyChart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import bar from 'plotly.js/lib/bar';
import pie from 'plotly.js/lib/pie';
import histogram from 'plotly.js/lib/histogram';
import box from 'plotly.js/lib/box';
import heatmap from 'plotly.js/lib/heatmap';
import { each, isArray, isObject } from 'lodash';

import { SeriesOptions, ValuesOptions } from '@/components/proptypes';
import { normalizeValue, updateData, prepareData, prepareLayout } from '@/visualizations/chart/plotly/utils';


Plotly.register([bar, pie, histogram, box]);
Plotly.register([bar, pie, histogram, box, heatmap]);
Plotly.setPlotConfig({
modeBarButtonsToRemove: ['sendDataToCloud'],
});
Expand All @@ -39,6 +40,7 @@ const Point = PropTypes.exact({
yError: PropTypes.any,
unused: PropTypes.any,
size: PropTypes.any,
zValue: PropTypes.any,
});

const Series = PropTypes.exact({
Expand Down

0 comments on commit 0f57bd3

Please sign in to comment.