bento-charts
Version:
Charts library for Bento-platform
74 lines • 5 kB
JavaScript
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