mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
e243a14c64
* Refactor around how visualizations/*.js are required * Reactifying FilterBox further * Fixing the auto-refresh on filtering events * Fixing preselected filters
123 lines
3.3 KiB
JavaScript
123 lines
3.3 KiB
JavaScript
// JS
|
|
const $ = window.$ = require('jquery');
|
|
const d3 = window.d3 || require('d3');
|
|
|
|
import React from 'react';
|
|
import ReactDOM from 'react-dom';
|
|
|
|
import Select from 'react-select';
|
|
import '../stylesheets/react-select/select.less';
|
|
|
|
import './filter_box.css';
|
|
|
|
class FilterBox extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
selectedValues: props.origSelectedValues,
|
|
};
|
|
}
|
|
render() {
|
|
const filters = Object.keys(this.props.filtersChoices).map((filter) => {
|
|
const data = this.props.filtersChoices[filter];
|
|
const id = 'fltbox__' + filter;
|
|
const maxes = {};
|
|
maxes[filter] = d3.max(data, function (d) {
|
|
return d.metric;
|
|
});
|
|
return (
|
|
<div>
|
|
{filter}
|
|
<Select
|
|
placeholder={`Select [${filter}]`}
|
|
key={filter}
|
|
multi={true}
|
|
value={this.state.selectedValues[filter]}
|
|
options={data.map((opt) => {
|
|
const perc = Math.round((opt.metric / maxes[opt.filter]) * 100);
|
|
const backgroundImage = (
|
|
'linear-gradient(to right, lightgrey, ' +
|
|
`lightgrey ${perc}%, rgba(0,0,0,0) ${perc}%`
|
|
);
|
|
const style = {
|
|
backgroundImage,
|
|
padding:'2px 5px',
|
|
};
|
|
return { value: opt.id, label: opt.id, style };
|
|
})}
|
|
onChange={(selectedOptions) => {
|
|
let vals;
|
|
if (selectedOptions) {
|
|
vals = selectedOptions.map((opt) => opt.value);
|
|
} else {
|
|
vals = null;
|
|
}
|
|
const selectedValues = this.state.selectedValues;
|
|
selectedValues[filter] = vals;
|
|
this.setState({ selectedValues });
|
|
this.props.onChange(filter, vals);
|
|
}}
|
|
/>
|
|
</div>
|
|
);
|
|
|
|
const preSelect = preSelectDict[filter];
|
|
if (preSelect !== undefined) {
|
|
filtersObj[filter].select2('val', preSelect);
|
|
}
|
|
});
|
|
return (
|
|
<div>
|
|
{filters}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
FilterBox.propTypes = {
|
|
origSelectedValues: React.PropTypes.objectOf(React.PropTypes.array),
|
|
filtersChoices: React.PropTypes.objectOf(React.PropTypes.array),
|
|
onChange: React.PropTypes.function,
|
|
};
|
|
FilterBox.defaultProps = {
|
|
origSelectedValues: {},
|
|
onChange: function () {},
|
|
};
|
|
|
|
function filterBox(slice) {
|
|
const filtersObj = {};
|
|
const d3token = d3.select(slice.selector);
|
|
|
|
const refresh = function () {
|
|
d3token.selectAll('*').remove();
|
|
const container = d3token
|
|
.append('div')
|
|
.classed('padded', true);
|
|
const preSelectDict = slice.getFilters() || {};
|
|
|
|
// filter box should ignore the dashboard's filters
|
|
const url = slice.jsonEndpoint({ extraFilters: false});
|
|
$.getJSON(url, (payload) => {
|
|
ReactDOM.render(
|
|
(
|
|
<FilterBox
|
|
filtersChoices={payload.data}
|
|
onChange={slice.setFilter}
|
|
origSelectedValues={slice.getFilters() || {}}
|
|
/>
|
|
),
|
|
document.getElementById(slice.containerId)
|
|
);
|
|
slice.done(payload);
|
|
})
|
|
.fail(function (xhr) {
|
|
slice.error(xhr.responseText, xhr);
|
|
});
|
|
};
|
|
return {
|
|
render: refresh,
|
|
resize: () => {},
|
|
};
|
|
}
|
|
|
|
module.exports = filterBox;
|