UNPKG

bento-charts

Version:
74 lines 5 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { GeoJSON, Popup } from 'react-leaflet'; import { interpolateRgb } from 'd3-interpolate'; import BentoMapContainer from './BentoMapContainer'; import MapLegendContinuous from './controls/MapLegendContinuous'; import MapLegendDiscrete from './controls/MapLegendDiscrete'; import { useTransformedChartData } from '../../util/chartUtils'; var DEFAULT_CATEGORY = ''; var POS_BOTTOM_RIGHT = 'bottomright'; var BentoChoroplethMap = function (_a) { var height = _a.height, center = _a.center, zoom = _a.zoom, tileLayer = _a.tileLayer, colorMode = _a.colorMode, features = _a.features, categoryProp = _a.categoryProp, onClick = _a.onClick, renderPopupBody = _a.renderPopupBody, params = __rest(_a, ["height", "center", "zoom", "tileLayer", "colorMode", "features", "categoryProp", "onClick", "renderPopupBody"]); var data = useTransformedChartData(params); var dataByFeatureCat = useMemo(function () { return Object.fromEntries(data.map(function (d) { return [d.x, d.y]; })); }, [data]); var minYVal = useMemo(function () { return Math.min.apply(Math, data.map(function (d) { return d.y; })); }, [data]); var maxYVal = useMemo(function () { return Math.max.apply(Math, data.map(function (d) { return d.y; })); }, [data]); var calculateColor = useCallback(function (v) { return colorMode.mode === 'continuous' ? interpolateRgb(colorMode.minColor, colorMode.maxColor)(((v !== null && v !== void 0 ? v : minYVal) - minYVal) / (maxYVal - minYVal)) : colorMode.colorFunction(v); }, [colorMode, minYVal, maxYVal]); var shapeStyle = useCallback(function (f) { var _a, _b; var fProps = (_a = f.properties) !== null && _a !== void 0 ? _a : {}; if (!Object.keys(fProps).includes(categoryProp)) { console.warn("Feature is missing category prop ".concat(categoryProp), f); } var cat = (_b = fProps[categoryProp]) !== null && _b !== void 0 ? _b : DEFAULT_CATEGORY; return { color: 'white', weight: 2, fillColor: calculateColor(dataByFeatureCat[cat]), fillOpacity: 1, // actual opacity set by fillColor }; }, [calculateColor, categoryProp, dataByFeatureCat]); var _b = useState(null), popupContents = _b[0], setPopupContents = _b[1]; var eventHandlers = useMemo(function () { return ({ click: function (e) { var _a; var feature = e.sourceTarget.feature; var fProps = (_a = feature.properties) !== null && _a !== void 0 ? _a : {}; var title = fProps.title ? "".concat(fProps.title, " (").concat(fProps[categoryProp], ")") : fProps[categoryProp]; setPopupContents(_jsxs("div", { children: [_jsx("h4", { style: { marginBottom: renderPopupBody ? 6 : 0 }, children: onClick ? (_jsx("a", { href: "#", onClick: function (e) { if (onClick) onClick(feature); e.preventDefault(); }, children: title })) : (_jsx("span", { children: title })) }), renderPopupBody ? renderPopupBody(feature, dataByFeatureCat[fProps[categoryProp]]) : null] })); }, }); }, [onClick, categoryProp, dataByFeatureCat, renderPopupBody]); var geoJsonLayer = useRef(null); useEffect(function () { // Bizarre workaround needed for react-leaflet when handling `features` change: // See https://github.com/PaulLeCam/react-leaflet/issues/332#issuecomment-731379795 if (geoJsonLayer.current) { geoJsonLayer.current.clearLayers().addData(features); } }, [features]); return (_jsxs(BentoMapContainer, { height: height, center: center, zoom: zoom, tileLayer: tileLayer, children: [_jsx(GeoJSON, { ref: geoJsonLayer, data: features, style: shapeStyle, eventHandlers: eventHandlers, children: _jsx(Popup, { children: popupContents }) }), colorMode.mode === 'continuous' ? (_jsx(MapLegendContinuous, { position: POS_BOTTOM_RIGHT, minColor: colorMode.minColor, minValue: minYVal, maxColor: colorMode.maxColor, maxValue: maxYVal })) : (_jsx(MapLegendDiscrete, { position: POS_BOTTOM_RIGHT, legendItems: colorMode.legendItems }))] })); }; export default BentoChoroplethMap; //# sourceMappingURL=BentoChoroplethMap.js.map