terriajs
Version:
Geospatial data visualization platform.
110 lines (97 loc) • 4.28 kB
JSX
;
import classNames from 'classnames';
import defined from 'terriajs-cesium/Source/Core/defined';
import knockout from 'terriajs-cesium/Source/ThirdParty/knockout';
import Loader from '../../Loader.jsx';
import ObserveModelMixin from '../../ObserveModelMixin';
import proxyCatalogItemUrl from '../../../Models/proxyCatalogItemUrl';
import React from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import URI from 'urijs';
import Styles from './legend.scss';
const Legend = createReactClass({
displayName: 'Legend',
mixins: [ObserveModelMixin],
propTypes: {
item: PropTypes.object
},
/* eslint-disable-next-line camelcase */
UNSAFE_componentWillMount() {
this.legendsWithError = {};
},
onImageError(legend) {
this.legendsWithError[legend.url] = true;
},
doesLegendHaveError(legend) {
const hasError = this.legendsWithError[legend.url];
if (!defined(hasError)) {
this.legendsWithError[legend.url] = false;
knockout.track(this.legendsWithError, [legend.url]);
}
return this.legendsWithError[legend.url];
},
renderLegend(legendUrl, i) {
const isImage = legendUrl.isImage();
const insertDirectly = !!legendUrl.safeSvgContent; // we only insert content we generated ourselves, not arbitrary SVG from init files.
const safeSvgContent = {__html: legendUrl.safeSvgContent};
// We proxy the legend so it's cached, and so that the Print/Export feature works with non-CORS servers.
// We make it absolute because the print view is opened on a different domain (about:blank) so relative
// URLs will not work.
const proxiedUrl = makeAbsolute(proxyCatalogItemUrl(this.props.item, legendUrl.url));
return (
<Choose>
<When condition={isImage && insertDirectly}>
<li key={i}
onError={this.onImageError.bind(this, legendUrl)}
className={classNames(Styles.legendSvg , {[Styles.legendImagehasError]: this.doesLegendHaveError(legendUrl)})}
dangerouslySetInnerHTML={safeSvgContent}
/>
</When>
<When condition={isImage}>
<li key={proxiedUrl} className={classNames({[Styles.legendImagehasError]: this.doesLegendHaveError(legendUrl)})}>
<a onError={this.onImageError.bind(this, legendUrl)}
href={proxiedUrl}
className={Styles.imageAnchor}
target="_blank" rel="noreferrer noopener">
<img src={proxiedUrl}/>
</a>
</li>
</When>
<Otherwise>
<li key={proxiedUrl}>
<a href={proxiedUrl}
target="_blank" rel="noreferrer noopener">Open legend in a separate tab
</a>
</li>
</Otherwise>
</Choose>);
},
render() {
return (
<ul className={Styles.legend}>
<div className={Styles.legendInner}>
<Choose>
<When condition={this.props.item.isLoading}>
<li className={Styles.loader}><Loader message={this.props.item.loadingMessage}/></li>
</When>
<Otherwise>
<For each="legend" index="i" of={this.props.item.legendUrls || []}>
{this.renderLegend(legend, i)}
</For>
</Otherwise>
</Choose>
</div>
</ul>
);
},
});
function makeAbsolute(url) {
const uri = new URI(url);
if (uri.protocol() !== 'http' && uri.protocol() !== 'https') {
return url;
} else {
return uri.absoluteTo(window.location.href).toString();
}
}
module.exports = Legend;