superset/caravel/assets/visualizations/filter_box.jsx
Maxime Beauchemin e243a14c64 Refactor around how visualizations/*.js are required (#913)
* Refactor around how visualizations/*.js are required

* Reactifying FilterBox further

* Fixing the auto-refresh on filtering events

* Fixing preselected filters
2016-08-11 21:39:10 -07:00

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;