UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

179 lines (158 loc) 5.69 kB
// Copyright (c) 2018 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 from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import {rgb} from 'd3-color'; import ColorLegend from 'components/common/color-legend'; import {DIMENSIONS} from 'constants/default-settings'; import {capitalizeFirstLetter} from 'utils/utils'; const StyledMapControlLegend = styled.div` padding: 10px 0 10px ${props => props.theme.mapControl.padding}px; font-size: 11px; border-bottom-color: ${props => props.theme.panelBorderColor}; border-bottom-style: solid; border-bottom-width: ${props => (props.last ? 0 : '1px')}; .legend--layer_name { font-size: 12px; padding-right: ${props => props.theme.mapControl.padding}px; color: ${props => props.theme.textColorHl}; font-weight: 500; } .legend--layer_type { color: ${props => props.theme.subtextColor}; font-weight: 500; font-size: 11px; padding-right: ${props => props.theme.mapControl.padding}px; } .legend--layer__title { padding-right: ${props => props.theme.mapControl.padding}px; } .legend--layer_by { color: ${props => props.theme.subtextColor}; } .legend--layer_color_field { color: ${props => props.theme.textColor}; font-weight: 500; } .legend--layer_color-legend { margin-top: 6px; } `; const VisualChannelMetric = ({name}) => ( <div className="legend--layer__title"> <span className="legend--layer_by">by </span> <span className="legend--layer_color_field">{name}</span> </div> ); const LayerSizeLegend = ({label, name}) => ( <div className="legend--layer_size-schema"> <p> <span className="legend--layer_by">{label}</span> </p> <VisualChannelMetric name={name} /> </div> ); const propTypes = { layers: PropTypes.array }; const SingleColorLegend = ({layer, width}) => ( <ColorLegend scaleType="ordinal" displayLabel={false} domain={['']} fieldType={null} range={[rgb(...layer.config.color).toString()]} width={width} /> ); const MultiColorLegend = ({layer, width}) => { const {visConfig, colorField, colorScale, colorDomain} = layer.config; return ( <ColorLegend scaleType={colorScale} displayLabel domain={colorDomain} fieldType={(colorField && colorField.type) || 'real'} range={visConfig.colorRange.colors} width={width} /> ); }; const MapLegend = ({layers}) => ( <div> {layers.map((layer, index) => { if (!layer.isValidToSave()) { return null; } const colorChannelConfig = layer.getVisualChannelDescription('color'); const enableColorBy = colorChannelConfig.measure; const width = DIMENSIONS.mapControl.width - 2 * DIMENSIONS.mapControl.padding; return ( <StyledMapControlLegend className="legend--layer" last={index === layers.length - 1} key={index} > <div className="legend--layer_name">{layer.config.label}</div> <div className="legend--layer_type">{`${capitalizeFirstLetter( layer.name )} color`}</div> <div className="legend--layer_color-schema"> <div> {enableColorBy ? ( <VisualChannelMetric name={enableColorBy} /> ) : null} <div className="legend--layer_color-legend"> {enableColorBy ? <MultiColorLegend layer={layer} width={width}/> : <SingleColorLegend layer={layer} width={width}/> } </div> </div> </div> {Object.keys(layer.visualChannels) .filter(k => k !== 'color') .map(key => { const matchCondition = !layer.visualChannels[key].condition || layer.visualChannels[key].condition(layer.config); const enabled = layer.config[layer.visualChannels[key].field] || layer.visualChannels[key].defaultMeasure; const visualChannelDescription = layer.getVisualChannelDescription(key); if (matchCondition && enabled) { return ( <LayerSizeLegend key={key} label={visualChannelDescription.label} name={visualChannelDescription.measure} /> ); } return null; })} </StyledMapControlLegend> ); })} </div> ); MapLegend.propTypes = propTypes; export default MapLegend;