Estoy adaptando la biblioteca Crossfilter para visualizar algunos tweets que he estado recopilando desde Olympics. Estoy intentando extender esencialmente el ejemplo inicial de dos maneras:Redibujar histogramas con Crossfilter y D3
- En lugar de mostrar una lista de vuelos basados en el conjunto de datos original, quiero mostrar listas de elementos de otro conjunto de datos introducido por los elementos seleccionados actualmente por crossfilter.
- Cambia entre diferentes orígenes de datos y vuelve a cargar los histogramas y las tablas.
Tengo la parte (1) trabajando según lo planeado. Sin embargo, la parte (2) me está dando algunos problemas. Actualmente estoy cambiando el conjunto de datos seleccionando un nuevo "deporte" para mostrar o seleccionando un nuevo algoritmo de resumen. Al cambiar cualquiera de estos, creo que primero debo eliminar los filtros, cuadros y listas previamente creados y mostrados, y luego volver a cargar los nuevos datos.
Sin embargo, siendo algo nuevo en las visualizaciones del front-end, especialmente D3 y Crossfilter, no he descubierto cómo hacerlo, ni estoy seguro de cómo expresar mejor la pregunta.
Tengo un ejemplo de trabajo de mi problema here. Seleccionar un rango en Fecha y luego cambiar de Tiro con arco a Esgrima, y luego seleccionar Restablecer muestra un buen ejemplo de lo que está mal: no todos los datos nuevos están graficados.
Como se ha dicho, la mayor parte del código se tira forma el ejemplo Crossfilter y una Tutorial on making radial visualizations. He aquí algunos de los trozos de código clave que creo que son relevantes:
Selección de una nueva fuente de datos:
d3.selectAll("#sports a").on("click", function (d) {
var newSport = d3.select(this).attr("id");
activate("sports", newSport);
reloadData(activeLabel("sports"), activeLabel("methods"));
});
d3.selectAll("#methods a").on("click", function (d) {
var newMethod = d3.select(this).attr("id");
activate("methods", newMethod);
reloadData(activeLabel("sports"), activeLabel("methods"));
});
volver a cargar los datos:
function reloadData(sportName, methodName) {
var filebase = "/tweetolympics/data/tweet." + sportName + "." + methodName + ".all.";
var summaryList, tweetList, remaining = 2;
d3.csv(filebase + "summary.csv", function(summaries) {
summaries.forEach(function(d, i) {
d.index = i;
d.group = parseInt(d.Group);
d.startTime = parseTime(d.Start);
d.meanTime = parseTime(d.Mean);
});
summaryList = summaries;
if (!--remaining)
plotSportData(summaryList, tweetList);
});
d3.csv(filebase + "groups.csv", function(tweets) {
tweets.forEach(function(d, i) {
d.index = i;
d.group = parseInt(d.Group);
d.date = parseTime(d.Time);
});
tweetList = tweets;
if (!--remaining)
plotSportData(summaryList, tweetList);
});
}
y cargar el filtro cruzado usando los datos:
function plotSportData(summaries, tweets) {
// Create the crossfilter for the relevant dimensions and groups.
var tweet = crossfilter(tweets),
all = tweet.groupAll(),
date = tweet.dimension(function(d) { return d3.time.day(d.date); }),
dates = date.group(),
hour = tweet.dimension(function(d) { return d.date.getHours() + d.date.getMinutes()/60; }),
hours = hour.group(Math.floor),
cluster = tweet.dimension(function(d) { return d.group; }),
clusters = cluster.group();
var charts = [
// The first chart tracks the hours of each tweet. It has the
// standard 24 hour time range and uses a 24 hour clock.
barChart().dimension(hour)
.group(hours)
.x(d3.scale.linear()
.domain([0, 24])
.rangeRound([0, 10 * 24])),
// more charts added here similarly...
];
// Given our array of charts, which we assume are in the same order as the
// .chart elements in the DOM, bind the charts to the DOM and render them.
// We also listen to the chart's brush events to update the display.
var chart = d3.selectAll(".chart")
.data(charts)
.each(function(chart) { chart.on("brush", renderAll)
.on("brushend", renderAll); });
// Render the initial lists.
var list = d3.selectAll(".list")
.data([summaryList]);
// Print the total number of tweets.
d3.selectAll("#total").text(formatNumber(all.value()));
// Render everything..
renderAll();
Supongo que debería comenzar plotSportData
con algo que borra el antiguo conjunto de datos, pero no estoy seguro de cómo debería ser. Cualquier sugerencia o pensamiento sería sumamente apreciado.
Gracias por compartir, no hay muchos ejemplos disponibles de filtros cruzados. Buena suerte con tu proyecto. –