kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
307 lines (282 loc) • 9.27 kB
JavaScript
// Copyright (c) 2023 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import React, {Component} from 'react';
import PropTypes from 'prop-types';
// import styled from "styled-components";
import {connect} from 'react-redux';
import {externalDatasetDownload} from '../../../store/actions/datasetActions';
import {withStyles} from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
// import Avatar from "@material-ui/core/Avatar";
import Typography from '@material-ui/core/Typography';
// import ReactPaginate from "react-paginate";
import Pagination from 'material-ui-flat-pagination';
import LoadingSpinner from '../loading-spinner';
import Radio from '@material-ui/core/Radio';
const styles = theme => ({
root: {
flexGrow: 1,
height: '320px'
},
button: {
margin: theme.spacing.unit,
maxHeight: '30px'
}
});
/*
Inspired by https://github.com/okonet/react-dropzone/blob/master/src/index.js
*/
export class ExternalDatasetsUpload extends Component {
state = {
currentPage: 1,
datasetsPerPage: 4,
offset: 0,
datasetFilter: '',
filteredDatasets: [],
selectedValue: ''
};
// static propTypes = {
// onUpload: PropTypes.func.isRequired
// };
// _setState = s => {
// this.setState({ [s]: true });
// };
_handlePageChange = (offset, page) => {
// console.log("active page is" + page);
// console.log(offset, page);
this.setState({offset, currentPage: page});
};
_onMount = datasets => {
return datasets.map(dataset => this.setState({[dataset.id]: false}));
};
componentDidMount() {
// console.log(this.state);
// this.setState({datasets: this.props.dataset.datasets})
const datasets = this.props.dataset.externalDatasets;
if (datasets) {
this._onMount(datasets);
}
}
_loadData(response, file) {
return file;
}
_downloadDataset = dataset => {
this.props.dispatch(externalDatasetDownload(dataset));
};
_files = () => {
var files = [];
const datasetId = this.state;
for (const [key, value] of Object.entries(datasetId)) {
if (value === true) {
const datasets = this.props.dataset.externalDatasets;
datasets.map(dataset => {
if (dataset.id === key) {
// console.log("reached")
return this._downloadDataset(dataset);
// console.log(dataset);
}
return dataset;
});
}
}
return files;
};
_onClick = () => {
// return this._files();
const dataset = this.props.dataset.externalDatasets.map(dataset => {
if (dataset.id === this.state.selectedValue) {
return this._downloadDataset(dataset);
}
});
return dataset;
};
_onChange = ({target: {files}}) => {
files = this.props.dataset.listDatasets;
if (!files) {
return;
}
this.props.onUpload(files);
};
_handleChange = name => event => {
this.setState({[name]: event.target.checked});
};
handleRadioChange = event => {
this.setState({selectedValue: event.target.value});
};
_filterDatasets = datasetFilter => {
// console.log(datasetFilter);
const {externalDatasets} = this.props.dataset;
const filteredDatasets = externalDatasets.filter(dataset => {
const datasetName = dataset.name.toLowerCase();
return datasetName.indexOf(datasetFilter.toLowerCase()) !== -1;
});
this.setState({
filteredDatasets
});
};
_handleFilterChange = e => {
this.setState({
datasetFilter: e.target.value
});
this._filterDatasets(e.target.value);
};
render() {
const {classes} = this.props;
let {externalDatasets} = this.props.dataset;
const {
currentPage,
datasetsPerPage,
filteredDatasets,
datasetFilter
} = this.state;
// const filtercurrentExternalDatasets = [{ name: "shishir" }];
const indexOfLastDataset = currentPage * datasetsPerPage;
const indexOfFirstDataset = indexOfLastDataset - datasetsPerPage;
// console.log("filtered datasets", filteredDatasets);
// console.log(filtercurrentExternalDatasets);
let currentExternalDatasets = [];
// console.log(datasetFilter.length);
if (datasetFilter.length === 0) {
currentExternalDatasets = externalDatasets.slice(
indexOfFirstDataset,
indexOfLastDataset
);
} else {
currentExternalDatasets = filteredDatasets.slice(
indexOfFirstDataset,
indexOfLastDataset
);
externalDatasets = filteredDatasets;
}
// console.log(currentExternalDatasets);
const renderExternalDatasets = currentExternalDatasets.map(dataset => {
const ID = dataset.id.toString();
// console.log(ID);
return (
<Grid
key={dataset.id}
item
xs={12}
style={{paddingBottom: '0px', width: '100%'}}
>
<Paper className={classes.paper}>
<Grid container wrap="nowrap" spacing={16} style={{margin: 'auto'}}>
<Grid item style={{padding: '0px'}}>
<Radio
checked={this.state.selectedValue === ID}
onChange={this.handleRadioChange}
value={dataset.id}
name="radio-button-demo"
aria-label="A"
/>
{/* <Checkbox
// checked={dataset.id}
onChange={this._handleChange(ID)}
value={dataset.name}
/> */}
</Grid>
<Grid item xs style={{margin: 'auto'}}>
<Typography>{dataset.name}</Typography>
</Grid>
</Grid>
</Paper>
</Grid>
);
});
const _renderButton = () => {
if (this.props.ui.progressAddDataStatus === 'OPEN') {
return (
<div style={{margin: 'auto'}}>
<LoadingSpinner />
</div>
);
}
return (
<Button className={classes.button} onClick={this._onClick}>
Add Data
</Button>
);
};
return (
<React.Fragment>
<div className={classes.root} style={{display: 'grid'}}>
{/* <CustomInput
borderColor="white"
labelText="Search"
id="email"
change={this._handleFilterChange}
formControlProps={{
fullWidth: true
}}
/> */}
<div style={{marginLeft: '12px'}}>
<label htmlFor="filter">Search: </label>
<input
style={{
borderTopStyle: 'hidden',
borderLeftStyle: 'hidden',
borderRightStyle: 'hidden',
borderBottomStyle: 'solid',
borderBottomWidth: 'thin',
borderBottomColor: 'lightgray'
}}
type="text"
id="filter"
value={this.state.datasetFilter}
onChange={this._handleFilterChange}
/>
</div>
<Grid
container
spacing={24}
style={{
display: 'inline-block',
margin: 'auto',
width: '100%',
minHeight: '240px'
}}
>
{renderExternalDatasets}
</Grid>
<Pagination
style={{margin: 'auto'}}
otherPageColor="black"
activePage={this.state.currentPage}
limit={this.state.datasetsPerPage}
offset={this.state.offset}
total={externalDatasets.length}
onClick={(e, offset, page) => this._handlePageChange(offset, page)}
/>
{_renderButton()}
</div>
</React.Fragment>
);
}
}
ExternalDatasetsUpload.propTypes = {
classes: PropTypes.object.isRequired
};
const mapStateToProps = state => state;
export default connect(
mapStateToProps,
null
)(withStyles(styles)(ExternalDatasetsUpload));