Filtrar con segmentaciones
Las segmentaciones son los controles de filtro que el autor colocó en el mapa. Las fichas de la izquierda se crean a partir de lo que informa el mapa (las segmentaciones, los valores que ofrece cada una y su estado actual) y se mantienen sincronizadas con las tarjetas de segmentación del propio mapa (arriba a la derecha del mapa): haga clic en una ficha y la tarjeta la sigue; use una tarjeta y las fichas la siguen. Establecer una segmentación desde script equivale exactamente a que el lector la use, así que todas las capas y gráficos enlazados a ella la siguen.
Abrir este ejemplo por separado
Qué observar
getSlicers()las enumera;getSlicerValues()devuelve los valores que ofrece una segmentación de lista.- El estado de una segmentación de lista es
{ values: [...] };nulllo borra. Los demás tipos aceptanvalue,range,date,dateRange,relativeDate,timeRangeotoggled. - Un solo controlador de
slicerChangedcubre sus cambios (reason: "command") y los del lector ("user"). - Ocultar una segmentación la desactiva: su selección deja de filtrar, como ocurre en un marcador. Para filtrar sin ninguna tarjeta en el mapa, use filtros declarados (el ejemplo siguiente).
El código
La página completa. Ponga su propio id de publicación y pida al autor del mapa que añada su sitio a sus orígenes permitidos.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Filter with slicers - Icon Map Embed API</title>
<link rel="stylesheet" href="https://www.icon-map.com/embed-examples/examples.css"> <!-- demo styling only -->
</head>
<body>
<div class="ex-main">
<div class="ex-side">
<div id="panels">loading...</div>
<h2>Result</h2>
<pre class="ex-readout" id="result"></pre>
<div class="ex-chips" style="margin-top:10px">
<button id="clear">Clear all</button>
<button id="fit">Frame the result</button>
</div>
</div>
<div id="map"></div>
</div>
<script src="https://www.icon-map.com/js/iconmap-embed/2/iconmap-embed.umd.min.js"></script>
<script>
const el = document.getElementById("map");
const map = IconMapEmbed.embed(el, {
publishId: "pub_...",
// The map is a globe: let this page's own background show in the space around it.
background: "transparent",
chrome: { legend: false, layerControl: false, bookmarksBar: false, tourTransport: false },
// The map's slicer cards stay on (top right): use one and the chips follow, click a chip and
// the card follows. Only the chart is hidden. Hiding a slicer would switch it OFF - to filter
// with no card on the map, use filters instead (see "Filter from your page").
visibility: { visuals: { "chart-continent": false } },
events: ["slicerChanged"],
});
map.ready.catch((error) => console.error(error.code, error.message));
const chosen = {}; // slicerId -> Set of values
// The slicers, their fields and the values each offers all come from the map.
map.getSlicers().then(async (slicers) => {
const host = document.getElementById("panels");
host.textContent = "";
for (const slicer of slicers) {
chosen[slicer.id] = new Set(slicer.state?.values ?? []);
const { values } = await map.getSlicerValues({ slicerId: slicer.id });
const title = Object.assign(document.createElement("h2"), { textContent: slicer.name });
const chips = Object.assign(document.createElement("div"), { className: "ex-chips" });
for (const value of values) {
const chip = Object.assign(document.createElement("button"), { textContent: String(value).replace(/^\d\. /, "") });
chip.dataset.slicer = slicer.id;
chip.dataset.value = value;
chip.onclick = () => toggle(slicer.id, String(value));
chips.append(chip);
}
host.append(title, chips);
}
paint();
});
// Setting a slicer is exactly the reader using it: every layer and chart bound to it follows.
// A list slicer's state is { values: [...] }; null clears it.
function toggle(slicerId, value) {
const set = chosen[slicerId];
set.has(value) ? set.delete(value) : set.add(value);
return map.setSlicerState({ slicerId, state: set.size ? { values: [...set] } : null });
}
document.getElementById("clear").onclick = () => map.clearAllSlicers();
document.getElementById("fit").onclick = () => map.fitLayer({ layerId: "cities", padding: 30, maxZoom: 6 });
// One handler covers your own changes (reason "command") and the reader's ("user").
map.on("slicerChanged", ({ slicerId, state }) => {
chosen[slicerId] = new Set(state?.values ?? []);
setTimeout(paint, 300); // give the map a moment to re-filter before counting
});
async function paint() {
for (const chip of document.querySelectorAll("[data-slicer]")) {
chip.classList.toggle("on", chosen[chip.dataset.slicer]?.has(chip.dataset.value) === true);
}
const stats = await map.getLayerStats({ layerId: "cities" });
document.getElementById("result").textContent = `${stats.visibleFeatureCount.toLocaleString()} cities match`;
}
</script>
</body>
</html>