Merge pull request #3 from SPFxAppDev/feature/legend
Updated Legend control (UI)
This commit is contained in:
commit
6644f13f32
|
@ -172,47 +172,6 @@
|
||||||
border: solid 1px $ms-color-themeDarker !important;
|
border: solid 1px $ms-color-themeDarker !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-legend {
|
|
||||||
display: flex;
|
|
||||||
margin-top: 5px;
|
|
||||||
|
|
||||||
&-title {
|
|
||||||
font-weight: 700;
|
|
||||||
padding-right: 4px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-marker-wrapper {
|
|
||||||
position: relative;
|
|
||||||
height: 36px;
|
|
||||||
float: left;
|
|
||||||
|
|
||||||
& > div {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
height: 18px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.map-icon,
|
|
||||||
.map-icon i {
|
|
||||||
font-size: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.map-icon {
|
|
||||||
left: 3px;
|
|
||||||
top: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
margin: 0 10px 0 16px;
|
|
||||||
padding: 1px 0;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel-footer {
|
.panel-footer {
|
||||||
button {
|
button {
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
|
|
|
@ -19,7 +19,8 @@ import { isFunction } from 'lodash';
|
||||||
import { MarkerIcon } from './MarkerIcon';
|
import { MarkerIcon } from './MarkerIcon';
|
||||||
import MarkerClusterGroup from 'react-leaflet-markercluster';
|
import MarkerClusterGroup from 'react-leaflet-markercluster';
|
||||||
import * as strings from 'MapWebPartStrings';
|
import * as strings from 'MapWebPartStrings';
|
||||||
import SearchPlugin from './plugin/SearchPlugin';
|
import SearchPlugin from './plugins/search/SearchPlugin';
|
||||||
|
import LegendPlugin from './plugins/legend/LegendPlugin';
|
||||||
|
|
||||||
interface IMapState {
|
interface IMapState {
|
||||||
markerItems: IMarker[];
|
markerItems: IMarker[];
|
||||||
|
@ -151,9 +152,10 @@ export default class Map extends React.Component<IMapProps, IMapState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
{this.renderSearchBox()}
|
{this.renderSearchBox()}
|
||||||
|
{this.renderLegend(isZoomControlEnabled)}
|
||||||
</MapContainer>
|
</MapContainer>
|
||||||
|
|
||||||
{this.renderLegend()}
|
|
||||||
|
|
||||||
{this.props.isEditMode &&
|
{this.props.isEditMode &&
|
||||||
<ContextualMenu
|
<ContextualMenu
|
||||||
|
@ -319,26 +321,14 @@ export default class Map extends React.Component<IMapProps, IMapState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderLegend(): JSX.Element {
|
private renderLegend(isZoomControlEnabled: boolean): JSX.Element {
|
||||||
if(!getDeepOrDefault<boolean>(this.props, "plugins.legend", false) || isNullOrEmpty(this.state.markerCategories)) {
|
if(!getDeepOrDefault<boolean>(this.props, "plugins.legend", false) || isNullOrEmpty(this.state.markerCategories)) {
|
||||||
return (<></>);
|
return (<></>);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='map-legend'>
|
<LegendPlugin isZoomControlVisible={isZoomControlEnabled} markerCategories={this.state.markerCategories} />
|
||||||
<span className="map-legend-title">{strings.LegendLabel}:</span>
|
);
|
||||||
{this.state.markerCategories.map((cat: IMarkerCategory): JSX.Element => {
|
|
||||||
return (
|
|
||||||
<div key={`legend_${cat.id}`}>
|
|
||||||
<div className='map-legend-marker-wrapper'>
|
|
||||||
<div style={{}}>
|
|
||||||
<MarkerIcon {...cat.iconProperties} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Label style={{}}>{cat.name}</Label>
|
|
||||||
</div>);
|
|
||||||
})}
|
|
||||||
</div>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderSearchBox(): JSX.Element {
|
private renderSearchBox(): JSX.Element {
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
|
||||||
|
|
||||||
|
|
||||||
|
.map-plugin-legend {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
|
||||||
|
&-bottom {
|
||||||
|
top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
outline: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
height: 32px;
|
||||||
|
border: 2px solid rgba(0,0,0,0.2);
|
||||||
|
background-clip: padding-box;
|
||||||
|
font-size: 1.4em;
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global {
|
||||||
|
.map-legend {
|
||||||
|
margin: 10px;
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
font-weight: 700;
|
||||||
|
// padding-right: 4px;
|
||||||
|
// font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-marker-item {
|
||||||
|
display: flex;
|
||||||
|
padding: 5px 10px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&-icon {
|
||||||
|
width: 35px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-marker-wrapper {
|
||||||
|
position: relative;
|
||||||
|
height: 36px;
|
||||||
|
// float: left;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin: 0 10px 0 16px;
|
||||||
|
padding: 1px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
import { Callout } from '@microsoft/office-ui-fabric-react-bundle';
|
||||||
|
import { randomString } from '@spfxappdev/utility';
|
||||||
|
import * as strings from 'MapWebPartStrings';
|
||||||
|
import { Icon, Label, Separator } from 'office-ui-fabric-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { IMarkerCategory } from '../../IMapProps';
|
||||||
|
import { MarkerIcon } from '../../MarkerIcon';
|
||||||
|
import styles from './LegendPlugin.module.scss';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export interface ILegendPluginProps {
|
||||||
|
markerCategories: IMarkerCategory[];
|
||||||
|
isZoomControlVisible: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ILegendPluginState {
|
||||||
|
isCalloutVisible: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class LegendPlugin extends React.Component<ILegendPluginProps, ILegendPluginState> {
|
||||||
|
|
||||||
|
public state: ILegendPluginState = {
|
||||||
|
isCalloutVisible: false
|
||||||
|
};
|
||||||
|
|
||||||
|
private randomId: string;
|
||||||
|
|
||||||
|
constructor(props: ILegendPluginProps) {
|
||||||
|
super(props);
|
||||||
|
this.randomId = `map_legend_${randomString(6)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): React.ReactElement<ILegendPluginProps> {
|
||||||
|
|
||||||
|
let cssClass = styles['map-plugin-legend'];
|
||||||
|
if(this.props.isZoomControlVisible) {
|
||||||
|
cssClass += ' ' + styles['map-plugin-legend-bottom'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`leaflet-top leaflet-left ${cssClass}`}>
|
||||||
|
<div className="leaflet-control leaflet-bar">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
id={this.randomId}
|
||||||
|
onClick={() => {
|
||||||
|
const isVisible: boolean = this.state.isCalloutVisible ? false : true;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
isCalloutVisible: isVisible
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon iconName="Info" />
|
||||||
|
</button>
|
||||||
|
<Callout
|
||||||
|
target={`#${this.randomId}`}
|
||||||
|
onDismiss={() => { this.setState({ isCalloutVisible: false }); }}
|
||||||
|
hidden={!this.state.isCalloutVisible}>
|
||||||
|
<div className='map-legend'>
|
||||||
|
<Label className="map-legend-title">{strings.LegendLabel}</Label>
|
||||||
|
<Separator />
|
||||||
|
{this.props.markerCategories.map((cat: IMarkerCategory): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<div key={`legend_${cat.id}`} className="map-legend-marker-item">
|
||||||
|
<div className='map-legend-marker-item-icon'>
|
||||||
|
<div className='map-legend-marker-wrapper'>
|
||||||
|
<div style={{}}>
|
||||||
|
<MarkerIcon {...cat.iconProperties} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Label>{cat.name}</Label>
|
||||||
|
</div>);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</Callout>
|
||||||
|
</div>
|
||||||
|
</div>);
|
||||||
|
}
|
||||||
|
}
|
|
@ -100,7 +100,6 @@ export default class SearchPlugin extends React.Component<ISearchPluginProps, IS
|
||||||
|
|
||||||
const response = await fetch(`${this.props.nominatimUrl}?format=json&limit=${this.props.resultLimit}&q=${searchTerm}`);
|
const response = await fetch(`${this.props.nominatimUrl}?format=json&limit=${this.props.resultLimit}&q=${searchTerm}`);
|
||||||
const responseJson = await response.json();
|
const responseJson = await response.json();
|
||||||
console.log("SSC", responseJson);
|
|
||||||
return responseJson;
|
return responseJson;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue