UNPKG

terriajs

Version:

Geospatial data visualization platform.

105 lines (86 loc) 3.3 kB
import React from 'react'; import PropTypes from 'prop-types'; import createReactClass from 'create-react-class'; import FeatureDetection from 'terriajs-cesium/Source/Core/FeatureDetection'; import DataUri from '../../Core/DataUri'; import Dropdown from '../Generic/Dropdown'; import Icon from '../Icon.jsx'; import Styles from './feature-info-download.scss'; const FeatureInfoDownload = createReactClass({ propTypes: { data: PropTypes.object.isRequired, name: PropTypes.string.isRequired, viewState: PropTypes.object.isRequired, canUseDataUri: PropTypes.bool }, getDefaultProps() { return { canUseDataUri: !(FeatureDetection.isInternetExplorer() || (/Edge/).exec(navigator.userAgent)) }; }, getLinks() { return [ { href: DataUri.make('csv', generateCsvData(this.props.data)), download: `${this.props.name}.csv`, label: 'CSV' }, { href: DataUri.make('json', JSON.stringify(this.props.data)), download: `${this.props.name}.json`, label: 'JSON' } ].filter(download => !!download.href); }, render() { const links = this.getLinks(); if (DataUri.checkCompatibility()) { return ( <Dropdown options={links} textProperty="label" theme={{dropdown: Styles.download, list: Styles.dropdownList, button: Styles.dropdownButton}} buttonClassName={Styles.btn}> <span className={Styles.iconDownload}><Icon glyph={Icon.GLYPHS.download}/></span> Download this Table&nbsp;</Dropdown> ); } else { return null; } } }); /** * Turns a 2-dimensional javascript object into a CSV string, with the first row being the property names and the second * row being the data. If the object is too hierarchical to be made into a CSV, returns undefined. */ function generateCsvData(data) { if (!data) { return; } const row1 = []; const row2 = []; const keys = Object.keys(data); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const type = typeof data[key]; // If data is too hierarchical to fit in a table, just return undefined as we can't generate a CSV. if (type === 'object' && data[key] !== null) { // covers both objects and arrays. return; } if (type === 'function') { // Ignore template functions we may add. continue; } row1.push(makeSafeForCsv(key)); row2.push(makeSafeForCsv(data[key])); } return row1.join(',') + '\n' + row2.join(','); } /** * Makes a string safe for insertion into a CSV by wrapping it in inverted commas (") and changing inverted commas within * it to double-inverted-commas ("") as per CSV convention. */ function makeSafeForCsv(value) { value = value ? `${value}` : ''; return '"' + value.replace(/"/g, '""') + '"'; } export default FeatureInfoDownload;