Zoom in and out on the map and see how nodes are combined and uncombined.
You can style combined nodes and links by using the onCombineNodes and onCombineLinks functions. In this example, we color the combined items based on the 'worst case' alert status of the children they contain, and we label each combined node with a numerical count of its child nodes.
import { MapWeave } from "mapweave/mapbox";
import { NetworkLayer } from "mapweave/layers";
import { networkData, defaultView } from "./data";
function priorityColor(items) {
const sortedByPriority = Object.values(items).sort((a, b) => a.data.priority - b.data.priority);
return sortedByPriority[0].color;
}
function onCombineNodes({ setStyle, nodes }) {
const count = Object.keys(nodes).length;
const color = priorityColor(nodes);
setStyle({
color,
label: {
text: count.toString(),
position: "center",
color: "black",
backgroundColor: "rgba(0,0,0,0)",
},
});
}
function onCombineLinks({ setStyle, links }) {
setStyle({ color: priorityColor(links) });
}
const mapweave = new MapWeave({ container: "mw", options: { accessToken: VITE_MAPBOX_API_KEY } });
const networkLayer = new NetworkLayer({
data: networkData,
options: { proximityCombine: { enabled: true, onCombineNodes, onCombineLinks } },
});
mapweave.addLayer(networkLayer);
mapweave.view(defaultView); const stateCapitals = [
["AL", 32.361538, -86.279118],
["AZ", 33.448457, -112.073844],
["AR", 34.736009, -92.331122],
["CA", 38.555605, -121.468926],
["CO", 39.7391667, -104.984167],
["CT", 41.767, -72.677],
["DE", 39.161921, -75.526755],
["FL", 30.4518, -84.27277],
["GA", 33.76, -84.39],
["ID", 43.613739, -116.237651],
["IL", 39.78325, -89.650373],
["IN", 39.790942, -86.147685],
["IA", 41.590939, -93.620866],
["KS", 39.04, -95.69],
["KY", 38.197274, -84.86311],
["LA", 30.45809, -91.140229],
["ME", 44.323535, -69.765261],
["MD", 38.972945, -76.501157],
["MA", 42.2352, -71.0275],
["MI", 42.7335, -84.5467],
["MN", 44.95, -93.094],
["MS", 32.32, -90.207],
["MO", 38.572954, -92.189283],
["MT", 46.595805, -112.027031],
["NE", 40.809868, -96.675345],
["NV", 39.160949, -119.753877],
["NH", 43.220093, -71.549127],
["NJ", 40.221741, -74.756138],
["NM", 35.667231, -105.964575],
["NY", 42.659829, -73.781339],
["NC", 35.771, -78.638],
["ND", 48.813343, -100.779004],
["OH", 39.962245, -83.000647],
["OK", 35.482309, -97.534994],
["OR", 44.931109, -123.029159],
["PA", 40.269789, -76.875613],
["RI", 41.82355, -71.422132],
["SC", 34, -81.035],
["SD", 44.367966, -100.336378],
["TN", 36.165, -86.784],
["TX", 30.266667, -97.75],
["UT", 40.7547, -111.892622],
["VT", 44.26639, -72.57194],
["VA", 37.54, -77.46],
["WA", 47.042418, -122.893077],
["WV", 38.349497, -81.633294],
["WI", 43.074722, -89.384444],
["WY", 41.145548, -104.802042],
];
const links = [
"AL-FL",
"AL-GA",
"AL-LA",
"AL-MS",
"AR-LA",
"AR-MO",
"AR-MS",
"AR-OK",
"AR-TN",
"AZ-NM",
"AZ-NV",
"AZ-UT",
"CA-NV",
"CA-OR",
"CO-NE",
"CO-NM",
"CO-OK",
"CO-UT",
"CO-WY",
"CT-MA",
"CT-NJ",
"CT-NY",
"CT-RI",
"DE-MD",
"DE-NJ",
"DE-PA",
"DE-VA",
"FL-GA",
"FL-SC",
"GA-SC",
"GA-TN",
"GA-WV",
"IA-KS",
"IA-MN",
"IA-MO",
"IA-NE",
"IA-WI",
"ID-MT",
"ID-NV",
"ID-OR",
"ID-UT",
"ID-WA",
"IL-IN",
"IL-MO",
"IL-WI",
"IN-KY",
"IN-MI",
"IN-OH",
"IN-TN",
"KS-MO",
"KS-NE",
"KS-OK",
"KY-OH",
"KY-TN",
"KY-WV",
"LA-MS",
"LA-TX",
"MA-ME",
"MA-NH",
"MA-RI",
"MD-PA",
"MD-VA",
"ME-NH",
"ME-VT",
"MI-OH",
"MI-PA",
"MI-WI",
"MN-ND",
"MN-NE",
"MN-WI",
"MO-OK",
"MO-TN",
"MS-TN",
"MT-ND",
"MT-UT",
"MT-WA",
"MT-WY",
"NC-SC",
"NC-VA",
"NC-WV",
"ND-SD",
"ND-WY",
"NE-SD",
"NH-NY",
"NH-VT",
"NJ-NY",
"NJ-PA",
"NM-OK",
"NM-TX",
"NV-OR",
"NV-UT",
"NY-PA",
"NY-VT",
"OH-PA",
"OH-WV",
"OK-TX",
"OR-WA",
"PA-WV",
"SD-WY",
"UT-WY",
"VA-WV",
];
const indexToPriority = [0, 1, 2, 2, 2, 2];
const priorityColors = ["#FF1764", "#FFB92E", "#0FAB7C"];
const statePriorities = Object.fromEntries(
stateCapitals.map(([id], index) => [id, indexToPriority[index % indexToPriority.length]])
);
export const networkData = Object.fromEntries([
...stateCapitals.map(([id, latitude, longitude]) => {
const priority = statePriorities[id];
const color = priorityColors[priority];
return [
id,
{
type: "node",
latitude,
longitude,
color,
size: 8,
data: { priority },
},
];
}),
...links.map((id) => {
const [id1, id2] = id.split("-");
const priority = Math.min(statePriorities[id1], statePriorities[id2]);
const color = priorityColors[priority];
return [id, { type: "link", id, id1, id2, color, data: { priority } }];
}),
]);
export const defaultView = {
latitude: 39,
longitude: -97,
zoom: 3,
}; <!doctype html>
<html>
<body>
<div id="mw"></div>
<script type="module" src="./code.js"></script>
</body>
</html> import React from "react";
import { createRoot } from "react-dom/client";
import { MapWeave } from "mapweave/react/mapbox";
import { NetworkLayer } from "mapweave/react/layers";
import { networkData, defaultView } from "./data";
const mapWeaveOptions = { accessToken: VITE_MAPBOX_API_KEY };
function priorityColor(items) {
const sortedByPriority = Object.values(items).sort((a, b) => a.data.priority - b.data.priority);
return sortedByPriority[0].color;
}
function onCombineNodes({ setStyle, nodes }) {
const count = Object.keys(nodes).length;
const color = priorityColor(nodes);
setStyle({
color,
label: {
text: count.toString(),
position: "center",
color: "black",
backgroundColor: "rgba(0,0,0,0)",
},
});
}
function onCombineLinks({ setStyle, links }) {
setStyle({ color: priorityColor(links) });
}
const networkLayerOptions = {
proximityCombine: {
enabled: true,
onCombineNodes,
onCombineLinks,
},
};
function Demo() {
return (
<MapWeave options={mapWeaveOptions} view={defaultView}>
<NetworkLayer data={networkData} options={networkLayerOptions} />
</MapWeave>
);
}
const root = createRoot(document.getElementById("mw"));
root.render(<Demo />); const stateCapitals = [
["AL", 32.361538, -86.279118],
["AZ", 33.448457, -112.073844],
["AR", 34.736009, -92.331122],
["CA", 38.555605, -121.468926],
["CO", 39.7391667, -104.984167],
["CT", 41.767, -72.677],
["DE", 39.161921, -75.526755],
["FL", 30.4518, -84.27277],
["GA", 33.76, -84.39],
["ID", 43.613739, -116.237651],
["IL", 39.78325, -89.650373],
["IN", 39.790942, -86.147685],
["IA", 41.590939, -93.620866],
["KS", 39.04, -95.69],
["KY", 38.197274, -84.86311],
["LA", 30.45809, -91.140229],
["ME", 44.323535, -69.765261],
["MD", 38.972945, -76.501157],
["MA", 42.2352, -71.0275],
["MI", 42.7335, -84.5467],
["MN", 44.95, -93.094],
["MS", 32.32, -90.207],
["MO", 38.572954, -92.189283],
["MT", 46.595805, -112.027031],
["NE", 40.809868, -96.675345],
["NV", 39.160949, -119.753877],
["NH", 43.220093, -71.549127],
["NJ", 40.221741, -74.756138],
["NM", 35.667231, -105.964575],
["NY", 42.659829, -73.781339],
["NC", 35.771, -78.638],
["ND", 48.813343, -100.779004],
["OH", 39.962245, -83.000647],
["OK", 35.482309, -97.534994],
["OR", 44.931109, -123.029159],
["PA", 40.269789, -76.875613],
["RI", 41.82355, -71.422132],
["SC", 34, -81.035],
["SD", 44.367966, -100.336378],
["TN", 36.165, -86.784],
["TX", 30.266667, -97.75],
["UT", 40.7547, -111.892622],
["VT", 44.26639, -72.57194],
["VA", 37.54, -77.46],
["WA", 47.042418, -122.893077],
["WV", 38.349497, -81.633294],
["WI", 43.074722, -89.384444],
["WY", 41.145548, -104.802042],
];
const links = [
"AL-FL",
"AL-GA",
"AL-LA",
"AL-MS",
"AR-LA",
"AR-MO",
"AR-MS",
"AR-OK",
"AR-TN",
"AZ-NM",
"AZ-NV",
"AZ-UT",
"CA-NV",
"CA-OR",
"CO-NE",
"CO-NM",
"CO-OK",
"CO-UT",
"CO-WY",
"CT-MA",
"CT-NJ",
"CT-NY",
"CT-RI",
"DE-MD",
"DE-NJ",
"DE-PA",
"DE-VA",
"FL-GA",
"FL-SC",
"GA-SC",
"GA-TN",
"GA-WV",
"IA-KS",
"IA-MN",
"IA-MO",
"IA-NE",
"IA-WI",
"ID-MT",
"ID-NV",
"ID-OR",
"ID-UT",
"ID-WA",
"IL-IN",
"IL-MO",
"IL-WI",
"IN-KY",
"IN-MI",
"IN-OH",
"IN-TN",
"KS-MO",
"KS-NE",
"KS-OK",
"KY-OH",
"KY-TN",
"KY-WV",
"LA-MS",
"LA-TX",
"MA-ME",
"MA-NH",
"MA-RI",
"MD-PA",
"MD-VA",
"ME-NH",
"ME-VT",
"MI-OH",
"MI-PA",
"MI-WI",
"MN-ND",
"MN-NE",
"MN-WI",
"MO-OK",
"MO-TN",
"MS-TN",
"MT-ND",
"MT-UT",
"MT-WA",
"MT-WY",
"NC-SC",
"NC-VA",
"NC-WV",
"ND-SD",
"ND-WY",
"NE-SD",
"NH-NY",
"NH-VT",
"NJ-NY",
"NJ-PA",
"NM-OK",
"NM-TX",
"NV-OR",
"NV-UT",
"NY-PA",
"NY-VT",
"OH-PA",
"OH-WV",
"OK-TX",
"OR-WA",
"PA-WV",
"SD-WY",
"UT-WY",
"VA-WV",
];
const indexToPriority = [0, 1, 2, 2, 2, 2];
const priorityColors = ["#FF1764", "#FFB92E", "#0FAB7C"];
const statePriorities = Object.fromEntries(
stateCapitals.map(([id], index) => [id, indexToPriority[index % indexToPriority.length]])
);
export const networkData = Object.fromEntries([
...stateCapitals.map(([id, latitude, longitude]) => {
const priority = statePriorities[id];
const color = priorityColors[priority];
return [
id,
{
type: "node",
latitude,
longitude,
color,
size: 8,
data: { priority },
},
];
}),
...links.map((id) => {
const [id1, id2] = id.split("-");
const priority = Math.min(statePriorities[id1], statePriorities[id2]);
const color = priorityColors[priority];
return [id, { type: "link", id, id1, id2, color, data: { priority } }];
}),
]);
export const defaultView = {
latitude: 39,
longitude: -97,
zoom: 3,
}; <!doctype html>
<html>
<body>
<div id="mw"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html>