colouring-montreal/app/src/frontend/legend.tsx

204 lines
6.5 KiB
TypeScript
Raw Normal View History

2018-11-29 17:00:53 -05:00
import React from 'react';
2019-05-27 13:26:29 -04:00
import PropTypes from 'prop-types';
2018-09-10 07:41:00 -04:00
2018-10-02 16:47:59 -04:00
import './legend.css';
2018-09-11 15:59:37 -04:00
2018-10-04 17:50:33 -04:00
const LEGEND_CONFIG = {
2018-12-03 04:35:14 -05:00
location: {
2019-05-27 11:31:48 -04:00
title: 'Location',
description: '% data collected',
2018-12-03 04:35:14 -05:00
elements: [
2019-01-22 16:46:07 -05:00
{ color: '#084081', text: '≥80%' },
{ color: '#0868ac', text: '6080%' },
{ color: '#43a2ca', text: '4060%' },
{ color: '#7bccc4', text: '2040%' },
{ color: '#bae4bc', text: '<20%' }
2018-12-03 04:35:14 -05:00
]
},
2019-07-07 14:21:08 -04:00
use: {
title: 'Use',
elements: []
},
type: {
title: 'Type',
elements: []
},
2018-12-03 04:35:14 -05:00
age: {
2019-05-27 11:31:48 -04:00
title: 'Age',
2018-12-03 04:35:14 -05:00
elements: [
2019-05-27 11:39:16 -04:00
{ color: '#f0eaba', text: '≥2000' },
{ color: '#fae269', text: '19802000' },
{ color: '#fbaf27', text: '19601980' },
{ color: '#e6711d', text: '19401960' },
{ color: '#d73d3a', text: '19201940' },
{ color: '#ba221c', text: '19001920' },
{ color: '#bb859b', text: '18801900' },
{ color: '#8b3654', text: '18601880' },
{ color: '#8f5385', text: '18401860' },
{ color: '#56619b', text: '18201840' },
{ color: '#6793b2', text: '18001820' },
{ color: '#83c3b3', text: '17801800' },
{ color: '#adc88f', text: '17601780' },
{ color: '#83a663', text: '17401760' },
{ color: '#77852d', text: '17201740' },
{ color: '#69814e', text: '17001720' },
{ color: '#d0c291', text: '16801700' },
{ color: '#918158', text: '16601680' },
{ color: '#7a5732', text: '<1660' },
2018-12-03 04:35:14 -05:00
]
},
size: {
2019-05-27 11:31:48 -04:00
title: 'Number of storeys',
2018-12-03 04:35:14 -05:00
elements: [
2019-05-27 11:39:16 -04:00
{ color: '#ffffcc', text: '≥40' },
{ color: '#fed976', text: '2039' },
{ color: '#fd8d3c', text: '1019' },
{ color: '#e31a1c', text: '69' },
{ color: '#800026', text: '15' },
2018-12-03 04:35:14 -05:00
]
},
construction: {
2019-05-27 11:31:48 -04:00
title: 'Construction',
2018-12-03 04:35:14 -05:00
elements: []
},
team: {
2019-05-27 11:31:48 -04:00
title: 'Team',
2018-12-03 04:35:14 -05:00
elements: []
},
2019-08-12 12:57:01 -04:00
sustainability: {
title: 'Sustainability',
2018-12-03 04:35:14 -05:00
elements: []
},
greenery: {
2019-05-27 11:31:48 -04:00
title: 'Greenery',
2018-12-03 04:35:14 -05:00
elements: []
},
planning: {
2019-05-27 11:31:48 -04:00
title: 'Planning',
elements: [
2019-05-27 11:39:16 -04:00
{ color: '#73ebaf', text: 'within conservation area' },
]
2018-12-03 04:35:14 -05:00
},
2019-07-07 14:21:08 -04:00
community: {
title: 'Community',
2018-12-03 04:35:14 -05:00
elements: []
2019-07-07 14:21:08 -04:00
},
like: {
title: 'Like Me',
elements: [
{ color: '#bd0026', text: '👍👍👍 ≥10' },
{ color: '#e31a1c', text: '👍👍 510' },
{ color: '#fc4e2a', text: '👍 4' },
{ color: '#fd8d3c', text: '👍 3' },
{ color: '#feb24c', text: '👍 2' },
{ color: '#fed976', text: '👍 1' },
]
2018-12-03 04:35:14 -05:00
}
2018-10-04 17:50:33 -04:00
};
class Legend extends React.Component<any, any> { // TODO: add proper types
static propTypes = { // TODO: generate propTypes from TS
slug: PropTypes.string,
color: PropTypes.string,
text: PropTypes.string
};
constructor(props) {
super(props);
this.state = {collapseList: false};
this.handleClick = this.handleClick.bind(this);
this.onResize= this.onResize.bind(this);
}
handleClick() {
this.setState(state => ({
collapseList: !state.collapseList
}));
}
2019-07-07 14:21:08 -04:00
componentDidMount() {
window.addEventListener('resize', this.onResize);
if (window && window.outerHeight) {
// if we're in the browser, pass in as though from event to initialise
this.onResize({target: window});
}
}
componentWillUnmount() {
window.removeEventListener('resize', this.onResize);
}
onResize(e) {
2019-07-07 14:21:08 -04:00
this.setState({collapseList: (e.target.outerHeight < 670 || e.target.outerWidth < 768)}); // magic number needs to be consistent with CSS expander-button media query
}
2019-07-07 14:21:08 -04:00
render() {
const details = LEGEND_CONFIG[this.props.slug] || {};
const title = details.title || "";
const elements = details.elements || [];
return (
<div className="map-legend">
<div className="logo">
<div className="grid">
<div className="row">
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
</div>
<div className="row">
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
</div>
<div className="row">
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
</div>
2019-01-22 16:23:35 -05:00
</div>
<h3 className="h3 logotype">
<span>Colouring</span>
<span>London</span>
</h3>
2019-01-22 16:23:35 -05:00
</div>
<h4 className="h4">{ title } {elements.length?<button className="expander-button btn btn-outline-secondary btn-sm" type="button" onClick={this.handleClick} >^</button>:null}</h4>
{
details.description?
<p>{details.description} </p>
: null
}
{
elements.length?
<ul className={this.state.collapseList ? 'collapse data-legend' : 'data-legend'} >
{
elements.map((item) => (
<li key={item.color} >
<span className="key" style={ { background: item.color } }>-</span>
{ item.text }
2019-07-07 14:21:08 -04:00
</li>
))
}
</ul>
: <p className="data-intro">Coming soon</p>
}
2019-01-22 16:23:35 -05:00
</div>
);
}
2018-10-04 17:50:33 -04:00
2019-05-27 13:26:29 -04:00
}
2018-09-10 07:41:00 -04:00
export default Legend;