Перерисовка гистограмм с помощью Crossfilter и D3
Я адаптируюCrossfilter библиотека для визуализации некоторых твитов, которые я собирал изОлимпийские игры, Я пытаюсь существенно расширить первоначальный пример двумя способами:
Instead of displaying lists of flights based on the original dataset, I want to display lists of items in another dataset keyed by items currently selected by crossfilter. Switch between different data sources and reload the histograms and tables.У меня есть часть (1), работающая, как и планировалось. Однако часть (2) доставляет мне некоторые неприятности. Я в настоящее время изменяю набор данных, выбирая новый вид спорта. для отображения или выбора нового суммарного алгоритма. При переключении любого из них, я считаю, что я должен сначала удалить фильтры, диаграммы и списки, ранее созданные и отображенные, а затем перезагрузить новые данные.
Тем не менее, будучи немного новым для визуализаций переднего плана, особенно D3 и Crossfilter, я не понял, как это сделать, и не уверен, как лучше сформулировать вопрос.
У меня есть рабочий пример моей проблемыВот, Выбор диапазона по дате, затем переключение из стрельбы из лука в фехтование и выбор сброса показывает хороший пример того, что не так: не все новые данные отображаются.
Как уже говорилось, большая часть кода извлекается изCrossfilter пример иУчебник по созданию радиальных визуализаций, Вот некоторые из ключевых фрагментов кода, которые я считаю актуальными:
Выбор нового источника данных:
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"));
});
Перезагрузка данных:
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);
});
}
И загрузка перекрестного фильтра с использованием данных:
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();
Я думаю, что я должен начатьplotSportData
с чем-то, что очищает старый набор данных, но я не уверен, как это должно выглядеть. Любые предложения или мысли будут высоко оценены.