我应该根据具有以下结构的JSON文档生成报告:
tables:
[
{
<some descriptors of the dataset>,
series:
[
key: ...,
values:
[
{ label: ..., value: ... },
...
]
]
},
...
]
JSON数组中可以有任意数量的表,任意序列。当然,每个系列都包含具有不同值的相同值集。对于每个表,我必须绘制一个包含给定数据和多条形图的表。我选择NVD3.js作为我的图表库。
由于我对JavaScript不是很有经验,所以我决定安全地使用它并遵循NVD3.js示例到字母,并以尽可能最古老和愚蠢的方式生成我需要的div和对象。一旦我对JS感觉更舒服,我就会实现模板等。这是我的JavaScript代码的缩短版本。我知道这太可怕了,所以请不要评判我。
var report_data = <stupid way of getting data, will use AJAX later>;
var my_div = document.getElementById('show-report');
report_data.tables.forEach(
function(table)
{
var newDiv = document.createElement('div');
newDiv.id = 'report_' + table.name;
var newHeader = document.createElement('h1');
newHeader.textContent = table.name;
newDiv.appendChild(newHeader);
// Generate style element for chart
var newStyle = document.createElement('style');
newStyle.textContent = '#' + table.name + '_chart svg {height: 500px;}';
newDiv.appendChild(newStyle);
// Generate <div><svg /></div> where chart will be placed
var chartDiv = document.createElement('div');
chartDiv.id = table.name + '_chart';
var svgEl = document.createElement('svg');
chartDiv.appendChild(svgEl);
newDiv.appendChild(chartDiv);
// Here I write the table and append it to the main div. Omitted because of intense shame.
my_div.appendChild(newDiv);
//Draw chart
nv.addGraph(
function()
{
var chart = nv.models.multiBarHorizontalChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.margin({top: 30, right: 20, bottom: 50, left: 175})
.tooltips(true)
.showControls(true);
chart.yAxis
.tickFormat(d3.format(',.2f'));
d3.select('#'+ table.name +'_chart svg')
.datum(table.series)
.transition().duration(250)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
}
);
}
);
所以,代码很糟糕,但它的工作原理......事情就是这样:它试图绘制每个图表并将其放在div中,但每个图表只显示没有样式的纯文本。见this Imgur album。如果我用一个表的名称“硬编码”一个div,它会在里面绘制图表。对我来说,看起来新创建的div没有应用NVD3.js CSS文件。我甚至不知道这是否可能,因为我对CSS的了解甚至比JavaScript还要少。
有没有人尝试过这样的事情,或者有人知道可能导致这种行为的原因吗?
答案 0 :(得分:4)
我刚刚遇到这个问题,在浏览了GitHub后我found the problem。
你不能使用document.createElement创建SVG元素,你必须使用document.createElementNS并为SVG指定xml名称空间,或者只使用d3的append方法:d3.select(...)。append(“svg” “)
我的问题特别涉及jQuery,这导致我使用:
生成SVG元素var $svg = d3.select($jqElement[0]).append("svg")
对于非jQuery用户,可以将常规DOM元素传递到d3.select
。在示例中,调用$jqElement[0]
来获取jQuery对象的DOM版本。