Filtrar desde su página
Los filtros declarados son las entradas que el autor del mapa decidió ofrecer a una página host. Son el único punto en el que un valor de su página llega a los datos del mapa, por lo que la regla es estricta: un nombre que el autor no declaró se rechaza antes de aplicar nada. Pulse Try an undeclared filter para verlo.
Abrir este ejemplo por separado
Qué observar
getFilterSchema()le indica los nombres, los tipos y los operadores: cree su interfaz a partir de él.- Un valor de lista significa "cualquiera de"; los números aceptan
{ low, high }, las fechas{ from, to }o un intervalo relativo como{ operator: "inLast", count: 30, unit: "days" }. - Al publicar un mapa, se declara automáticamente un filtro por cada columna a la que llega alguna de sus segmentaciones.
- Esta página oculta todas las tarjetas y aun así enumera los valores de cada filtro:
getSlicerValuesresponde también para una segmentación oculta. - Los filtros restringen lo que muestra el mapa; no son un límite de seguridad entre usuarios.
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 from your page - 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="filters">loading...</div>
<h2>Applied</h2>
<pre class="ex-readout" id="applied">{}</pre>
<div class="ex-chips" style="margin-top:10px">
<button id="clear">Clear filters</button>
<button id="bad">Try an undeclared filter</button>
</div>
<pre class="ex-readout" id="error" style="margin-top:8px;color:#ff8a8a"></pre>
</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 },
// Every card hidden: this page owns the filter UI. (getSlicerValues still answers for a hidden slicer.)
visibility: { visuals: { "chart-continent": false, "slicer-continent": false, "slicer-size": false, "slicer-capital": false } },
events: ["filtersChanged"],
});
map.ready.catch((error) => console.error(error.code, error.message));
const values = {}; // filter name -> Set
(async () => {
// The filters the map's AUTHOR declared. A page can set these and nothing else.
const schema = await map.getFilterSchema();
const host = document.getElementById("filters");
host.textContent = schema.length ? "" : "This map declares no filters.";
// Value lists: from the schema when the author fixed them, else from the slicer on the same column.
const slicers = await map.getSlicers();
for (const filter of schema) {
values[filter.name] = new Set();
let options = filter.values;
const slicer = slicers.find((s) => s.field === filter.column);
if (!options && slicer) options = (await map.getSlicerValues({ slicerId: slicer.id })).values;
host.append(Object.assign(document.createElement("h2"), { textContent: filter.label ?? slicer?.name ?? filter.name }));
const chips = Object.assign(document.createElement("div"), { className: "ex-chips" });
for (const option of options ?? []) {
const chip = Object.assign(document.createElement("button"), { textContent: String(option).replace(/^\d\. /, "") });
chip.onclick = () => {
const set = values[filter.name];
set.has(option) ? set.delete(option) : set.add(option);
chip.classList.toggle("on", set.has(option));
apply();
};
chips.append(chip);
}
host.append(chips);
}
})();
// setFilters replaces every filter value at once; a list means "any of".
function apply() {
const filters = {};
for (const [name, set] of Object.entries(values)) if (set.size) filters[name] = [...set];
return map.setFilters(filters).catch(show);
}
document.getElementById("clear").onclick = () => {
for (const set of Object.values(values)) set.clear();
for (const chip of document.querySelectorAll(".ex-chips button.on")) chip.classList.remove("on");
map.clearFilters();
};
// A name the author did not declare is refused before anything is applied.
document.getElementById("bad").onclick = () => map.setFilters({ salary: [100000] }).catch(show);
function show(error) {
document.getElementById("error").textContent = `${error.code}\n${error.message}`;
}
map.on("filtersChanged", ({ filters, reason }) => {
document.getElementById("error").textContent = "";
document.getElementById("applied").textContent = `${JSON.stringify(filters, null, 1)}\n(${reason})`;
});
</script>
</body>
</html>