使用和不使用 d3.json() 驱动 D3 图表
Driving a D3 chart with and without d3.json()
我有一段代码可以创建一个甜甜圈(即d3.layout.pie(((。
我曾经通过以下方式加载 JSON 数据
d3.json(jsonFilePath,
function(json) {
//logic
....
})
我的可视化是交互式的(即,甜甜圈的大小各不相同,包括 innerRadius 和"d"属性(。所以我正确地实现了三种情况,输入、删除和更新以及 attrTween 函数来转换"d"属性。
它一直工作到现在。我决定实现某种缓存机制(即,我有一个保存数据的变量,以便数据被预取一次,并在需要时再次重用(。我测试了缓存的行为,它正在工作。这是一个片段...
if(cache[name] == undefined) {
console.log('Loading data and create viz');
// Loading all the JSONs for this name
var remaining = revs.length;
// revs is an array w/ json file names to load (elements in the form r1, r4 etc.)
var current = {};
for (var i in revs) {
d3.json(revs[i] + ".json" , function(json) {
current["r"+json.revision] = json;
if (!--remaining) {
// Data loaded, here, hence setting cache
cache[appName] = current;
createViz(rev);
}
});
}
}
我说到重点。我用对包含加载的 JSON 字符串的缓存数据的简单访问替换了我过去加载数据的方式,所以现在我有看起来像的东西而不是上面的代码块
var currentCache = cache[someName];
var json = currentCache[revisionName];
当我检查 json 变量时,json 加载正确并且看起来不错。关键是现在过渡不再有效,我收到了很多消息,例如
Error: Problem parsing d="M2.1431318985078682e-14,-350A350,350 0 1,1 NaN,NaNLNaN,NaNA230.68565589945686,230.68565589945686 0 1,0 1.412542250532388e-14,-230.68565589945686Z"
我以前已经面对过这条消息,但现在问题是我不知道为什么会发生这种情况。代码保持不变,而不是使用 d3.json(( 我使用的是变量中的 json 字符串。有什么建议吗?
我附上部分代码以供参考...
// An array of objects such as {"name" : myObject, "calls" : 23}
var calls = json.children;
var donut = d3.layout.pie()
.value(function(d) { return d.calls; })
.sort(null)
var arcs = d3.select("#vizGroup")
.selectAll(".callSlice")
.data(donut(calls));
//update
arcs
.data(donut(calls))
.transition()
.duration(750)
.attrTween("d", arcTween)
.style("fill", function(d) { return somecolor(d.data.name); } )
//enter
arcs.enter()
.append("svg:path")
.style("fill", function(d) { return somecolor(d.data.name); } )
.attr("stroke", "#EEF")
.attr('class', 'callSlice')
.each(function(d) { this._current = d; })
.transition()
.duration(750)
.attrTween("d", arcTween)
//remove
arcs.exit().remove();
function arcTween(a) {
a.innerRadius = myScale(myVariable);
var i = d3.interpolate({
startAngle: this._current.startAngle,
endAngle: this._current.endAngle,
innerRadius: this._current.innerRadius}, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
您的代码段引用了一个未定义的变量rev
。此外,不要将 for-in 循环与数组一起使用。我假设你的意思是这样的:
for (var i = 0, n = revs.length; i < n; ++i) {
d3.json(revs[i] + ".json", function(json) {
var rev = revs[i];
/* do something with rev here */
});
}
或者等效地,像这样:
for (var i = 0, n = revs.length; i < n; ++i) {
var rev = revs[i];
d3.json(revs[i] + ".json", function(json) {
/* do something with rev here */
});
}
这些都不会按预期工作,因为 d3.json 回调是异步的,并且闭包不会捕获 for 循环当前迭代中rev
的值(或就此而言i
(:它们捕获引用,而不是值,因此当稍后调用回调时,所有回调都将在 for 循环的最后一次迭代中看到该值 ( revs.length
(, 不是调用每个 d3.json 时的值。
您可以通过使用闭包捕获值来解决此问题。例如:
for (var i = 0, n = revs.length; i < n; ++i) {
fetch(revs[i]);
}
function fetch(rev) {
d3.json(rev + ".json", function(json) {
/* do something with rev here */
});
}
这是有效的,因为rev
的每个唯一值都由函数 fetch
捕获。有关闭包的更多信息,请参阅:
- http://jibbering.com/faq/notes/closures/
您没有包含有错误的代码,我怀疑这是您的 JSON 缓存代码。我的猜测是,您仍在异步获取 JSON,但您正在尝试立即使用它。 d3.json()
采用一个在实际加载数据之前不调用的回调函数 - 我在您当前的代码中没有看到任何类似的结构,因此除非您以内联方式而不是从远程文件加载 JSON,否则这可能是问题所在。
无济于事,因为当您检查控制台时,数据已经加载 - 当您的代码实际运行时,您会遇到问题。
- Javascript:selenium Web驱动程序isDisplayed()不工作
- 试图在引导模式内动态生成图表,得到offsetWidth错误
- 角度图表;t显示在我的页面中
- Selenium Web驱动程序和javascript
- 更改使用Chart.js创建的图表中的轴线颜色
- addData()从最新图表中删除.js 2.1.3-怎么了
- 在Highcharts中,我们可以通过任何方式在渲染图表之前获得plotWidth和plotHeight
- 谷歌图表-如何更改整个表的css属性
- chart.series[id].remove()无法刷新高位图表/高位股票中其他系列的图例属性
- 正在等待呈现图表,直到加载数据为止
- 正在打印图表上的文本
- 剑道图表:如何创建热图
- 使用谷歌图表在x轴上绘制日期
- HTML5FileReader输出到D3.js图表
- 谷歌图表显示所有标签
- 如何在谷歌日历图表中使用布尔型列
- 如何在屏幕外或项目的中心视口中跟随YUI驱动的动画
- 谷歌图表API:添加空白行到时间线
- 使用和不使用 d3.json() 驱动 D3 图表
- 使用JSON为数据库驱动的图表获取图表值(highchart.js)