Filtrar com segmentações
As segmentações de dados são os controles de filtro que o autor colocou no mapa. Os chips à esquerda são construídos a partir do que o mapa informa (as segmentações, os valores que cada uma oferece e o estado atual) e ficam em sincronia com os cartões de segmentação do próprio mapa (no canto superior direito do mapa): clique em um chip e o cartão acompanha; use um cartão e os chips acompanham. Definir uma segmentação por script é exatamente o mesmo que o leitor usá-la, então todas as camadas e gráficos vinculados a ela acompanham.
Abrir este exemplo separadamente
O que observar
getSlicers()as lista;getSlicerValues()retorna os valores que uma segmentação de lista oferece.- O estado de uma segmentação de lista é
{ values: [...] };nulla limpa. Os outros tipos recebemvalue,range,date,dateRange,relativeDate,timeRangeoutoggled. - Um único manipulador de
slicerChangedcobre as suas alterações (reason: "command") e as do leitor ("user"). - Ocultar uma segmentação a desativa: sua seleção deixa de filtrar, como acontece em um indicador. Para filtrar sem nenhum cartão no mapa, use filtros declarados (o próximo exemplo).
O código
A página completa. Troque pelo seu próprio ID de publicação e peça ao autor do mapa que adicione seu site às origens permitidas dele.
<!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>