Files
superset2/superset/assets/javascripts/explorev2/components/ChartContainer.jsx
vera-liu 83d08b8b8f Get query button working in explorev2 (#1581)
* Get query buttonw working in explorev2

 - Create new endpoint for updating explore viz
 - Send over new form_data when query button is pressed

* Added endpoint test

* Changes based on comments

* Added docstring for endpoint, and query spec

* Remove white space around docstring
2016-11-16 13:21:53 -08:00

198 lines
5.2 KiB
JavaScript

import $ from 'jquery';
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { Panel } from 'react-bootstrap';
import visMap from '../../../visualizations/main';
import { d3format } from '../../modules/utils';
import ExploreActionButtons from '../../explore/components/ExploreActionButtons';
const propTypes = {
can_download: PropTypes.bool.isRequired,
slice_name: PropTypes.string.isRequired,
viz_type: PropTypes.string.isRequired,
height: PropTypes.string.isRequired,
containerId: PropTypes.string.isRequired,
json_endpoint: PropTypes.string.isRequired,
csv_endpoint: PropTypes.string.isRequired,
standalone_endpoint: PropTypes.string.isRequired,
query: PropTypes.string.isRequired,
column_formats: PropTypes.object,
data: PropTypes.any,
isChartLoading: PropTypes.bool,
};
class ChartContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
selector: `#${props.containerId}`,
mockSlice: {},
};
}
componentWillMount() {
this.setState({ mockSlice: this.getMockedSliceObject(this.props) });
}
componentDidMount() {
this.renderVis();
}
componentWillReceiveProps(nextProps) {
this.setState({ mockSlice: this.getMockedSliceObject(nextProps) });
}
componentDidUpdate() {
this.renderVis();
}
getMockedSliceObject(props) {
return {
viewSqlQuery: props.query,
data: {
csv_endpoint: props.csv_endpoint,
json_endpoint: props.json_endpoint,
standalone_endpoint: props.standalone_endpoint,
},
containerId: props.containerId,
jsonEndpoint: () => props.json_endpoint,
container: {
html: (data) => {
// this should be a callback to clear the contents of the slice container
$(this.state.selector).html(data);
},
css: (dim, size) => {
// dimension can be 'height'
// pixel string can be '300px'
// should call callback to adjust height of chart
$(this.state.selector).css(dim, size);
},
height: () => parseInt(props.height, 10) - 100,
show: () => { this.render(); },
get: (n) => ($(this.state.selector).get(n)),
find: (classname) => ($(this.state.selector).find(classname)),
},
width: () => this.chartContainerRef.getBoundingClientRect().width,
height: () => parseInt(props.height, 10) - 100,
selector: this.state.selector,
setFilter: () => {
// set filter according to data in store
// used in FilterBox.onChange()
},
getFilters: () => (
// return filter objects from viz.formData
{}
),
done: () => {
// finished rendering callback
},
error(msg, xhr) {
let errorMsg = msg;
let errHtml = '';
try {
const o = JSON.parse(msg);
if (o.error) {
errorMsg = o.error;
}
} catch (e) {
// pass
}
errHtml = `<div class="alert alert-danger">${errorMsg}</div>`;
if (xhr) {
const extendedMsg = this.getErrorMsg(xhr);
if (extendedMsg) {
errHtml += `<div class="alert alert-danger">${extendedMsg}</div>`;
}
}
$(this.state.selector).html(errHtml);
this.render();
$('span.query').removeClass('disabled');
$('.query-and-save button').removeAttr('disabled');
},
d3format: (col, number) => {
// mock d3format function in Slice object in superset.js
const format = this.props.column_formats[col];
return d3format(format, number);
},
};
}
renderVis() {
visMap[this.props.viz_type](this.state.mockSlice).render();
}
render() {
return (
<div className="chart-container">
<Panel
style={{ height: this.props.height }}
header={
<div
id="slice-header"
className="panel-title"
>
{this.props.slice_name}
<div className="pull-right">
<ExploreActionButtons
slice={this.state.mockSlice}
canDownload={this.props.can_download}
/>
</div>
</div>
}
>
{!this.props.isChartLoading &&
<div
id={this.props.containerId}
ref={(ref) => { this.chartContainerRef = ref; }}
className={this.props.viz_type}
/>
}
</Panel>
</div>
);
}
}
ChartContainer.propTypes = propTypes;
function mapStateToProps(state) {
return {
containerId: `slice-container-${state.viz.form_data.slice_id}`,
slice_name: state.viz.form_data.slice_name,
viz_type: state.viz.form_data.viz_type,
can_download: state.can_download,
csv_endpoint: state.viz.csv_endpoint,
json_endpoint: state.viz.json_endpoint,
standalone_endpoint: state.viz.standalone_endpoint,
query: state.viz.query,
column_formats: state.viz.column_formats,
data: state.viz.data,
isChartLoading: state.isChartLoading,
};
}
function mapDispatchToProps() {
return {};
}
export default connect(mapStateToProps, mapDispatchToProps)(ChartContainer);