我搜索了这个网站,发现了很多D3示例,但我很难让我的XML文件中的节点绑定到一个简单的D3条形图。这是我的XML文件:
<?xml version="1.0" encoding="UTF-8" ?>
<MTTR>
<MONTH>
<FixMonth>2012-12</FixMonth>
<AvgMTTR>31.4700000</AvgMTTR>
<DefectCaseCount>200</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-01</FixMonth>
<AvgMTTR>38.2764976</AvgMTTR>
<DefectCaseCount>217</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-02</FixMonth>
<AvgMTTR>28.5416666</AvgMTTR>
<DefectCaseCount>192</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-03</FixMonth>
<AvgMTTR>27.8351254</AvgMTTR>
<DefectCaseCount>279</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-04</FixMonth>
<AvgMTTR>27.2445141</AvgMTTR>
<DefectCaseCount>319</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-05</FixMonth>
<AvgMTTR>26.2034632</AvgMTTR>
<DefectCaseCount>231</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-06</FixMonth>
<AvgMTTR>32.1470588</AvgMTTR>
<DefectCaseCount>238</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-07</FixMonth>
<AvgMTTR>29.6721311</AvgMTTR>
<DefectCaseCount>244</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-08</FixMonth>
<AvgMTTR>29.3853211</AvgMTTR>
<DefectCaseCount>218</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-09</FixMonth>
<AvgMTTR>28.6966824</AvgMTTR>
<DefectCaseCount>211</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-10</FixMonth>
<AvgMTTR>28.6500000</AvgMTTR>
<DefectCaseCount>220</DefectCaseCount>
</MONTH>
<MONTH>
<FixMonth>2013-11</FixMonth>
<AvgMTTR>29.3197969</AvgMTTR>
<DefectCaseCount>197</DefectCaseCount>
</MONTH>
</MTTR>
我正在尝试使用Mike Bostock的简单条形图作为插入我的XML数据的模式,但没有运气。这是我正在使用的相关javascript代码:
--------- code snippet ------------
var dataset;
var parseDate = d3.time.format("%Y-%m").parse;
d3.xml("MTTR.xml", "application/xml", function(error, data) {
if (error) { return console.warn(error);
}
else { dataset = data;
console.log(dataset);
x.domain([0, d3.max(dataset, function(d) { return parseDate(d.FixMonth); })]);
y.domain([0, d3.max(dataset, function(d) { return d.AvgMTTR; })]);
}
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("MTTR");
svg.selectAll(".bar")
.data(dataset)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.FixMonth); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.AvgMTTR); })
.attr("height", function(d) { return height - y(d.AvgMTTR); });
});
function type(d) {
d.AvgMTTR = +d.AvgMTTR;
return d;
}
------------结束代码片段----------
我无法让parseDate和x.domain绑定工作。我也无法将FixMonth节点解析为字符串,以将值分配给x轴。任何提示都非常感激。
答案 0 :(得分:1)
我有点惊讶d3没有将XML数据转换为JSON的内置方法,但我想这是因为XML数据的结构变化很大。
对于您的数据集,所有数据值都作为标记名称而没有属性,此函数应该为您进行转换:
//a recursive function to convert simple xml to JSON
//tag names become object keys
//elements with the same tag are grouped into arrays
//tag attributes are ignored
var nestByTagName = d3.nest().key(function(d){
return d.tagName;
});
function xmlToJSON(xml) {
if (xml.children.length) {
var o = {}
var childTypes = nestByTagName.entries(xml.children);
childTypes.forEach(function(type) {
//each type, as returned by the nest function
//will be an object with type.key = tagName
//and type.values = array of xml child objects
if (type.values.length == 1) {
//only one child of this type
o[type.key] = xmlToJSON(type.values[0]);
}
else { // multiple children of this type
o[type.key] = type.values.map( function(v) {
return xmlToJSON(v);
});
//replace each xml object in the nested array
//with its JSON-ified version
}
});
return o;
}
else { //leaf node, return string value
return xml.textContent;
}
}
使用您的数据集实现,并通过一些解决方法将其作为小提琴阅读
输出到控制台:http://fiddle.jshell.net/22E9X/1/
在3秒超时后显示结果面板中的更改:http://fiddle.jshell.net/22E9X/2/
您想要用于d3制图的数据阵列位于dataset.mttr.months
。请注意,该函数不会执行任何操作来解析日期或从字符串转换数字;你仍然需要在你的访问器功能中这样做。唯一的另一个缺点是内部函数破坏了大小写混合标记名称。