我正在调整 Crossfilter库可视化我从 Olympics 收集的一些推文.我试图通过两种方式从本质上扩展初始示例:
- 我不想显示基于原始数据集的航类列表,而是想显示另一个数据集中的项目列表,该数据集以交叉过滤器当前选择的项目为键。
- 在不同数据源之间切换并重新加载直方图和表格。
我已经让第 (1) 部分按计划工作了。但是,第 (2) 部分给我带来了一些麻烦。我目前正在通过选择要显示的新“运动”或选择新的摘要算法来更改数据集。在切换其中任何一个时,我认为我应该首先删除以前创建和显示的过滤器、图表和列表,然后重新加载新数据。
但是,作为前端可视化的新手,尤其是 D3 和 Crossfilter,我还没有想出如何做到这一点,也不确定如何最好地表达这个问题。
我有一个问题的工作示例 here .在日期上选择一个范围,然后从射箭切换到击剑,然后选择重置显示了错误的一个很好的例子:并非所有新数据都被绘制出来。
如前所述,大部分代码是从 Crossfilter 中提取的示例和一个 Tutorial on making radial visualizations .以下是我认为相关的一些关键代码块:
选择一个新的数据源:
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
,但我不确定它应该是什么样子。任何建议或想法将不胜感激。
最佳答案
经过一夜的 sleep ,我想到了解决方案。
我只需要打电话
d3.selectAll(".chart").selectAll("svg").remove();
在 plotSportData
的开头,它将获取嵌套在 .chart
div 下的任何直方图并将其删除。如果没有要删除的元素,它将是空操作。
关于javascript - 使用 Crossfilter 和 D3 重绘直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11824354/