D3.js尝试实现可排序的SVG表
D3.js trying to implement sortable SVG table
正如我的标题所述,我正试图实现一个具有良好过渡的交互式表,这就是为什么我选择D3.js与SVG元素相结合的原因。
我设法实现了一个具有普通HTML元素(th,tr,td)的可排序表:
http://jsfiddle.net/recek/q6LE6/// create the table header
var thead = d3.select("thead").selectAll("th")
.data(d3.keys(jsonData[0]))
.enter().append("th").text(function(d){return d;})
.on("click", function(d){ return refreshTable(d);});
// fill the table
// create rows
var tr = d3.select("tbody").selectAll("tr").data(jsonData);
tr.enter().append("tr");
// create cells
var td = tr.selectAll("td").data(function(d){return d3.values(d);});
td.enter().append("td")
.text(function(d) {return d;});
//update?
if(sortOn !== null) {
// update rows
if(sortOn != previousSort){
tr.sort(function(a,b){return sort(a[sortOn], b[sortOn]);});
previousSort = sortOn;
}
else{
tr.sort(function(a,b){return sort(b[sortOn], a[sortOn]);});
previousSort = null;
}
//update cells
td.text(function(d) {return d;});
}
可以看到,当单击header元素时,表正确地对数据进行了排序。基于上面的表格,我开始实现这个表格的svg版本,这就是我到目前为止的进展:
http://jsfiddle.net/recek/v58zT/// create the table header
var header = headerGrp.selectAll("g")
.data(d3.keys(jsonData[0]))
.enter().append("g")
.attr("class", "header")
.attr("transform", function (d, i){
return "translate(" + i * fieldWidth + ",0)";
})
.on("click", function(d){ return refreshTable(d);});
header.append("rect")
.attr("width", fieldWidth-1)
.attr("height", fieldHeight);
header.append("text")
.attr("x", fieldWidth / 2)
.attr("y", fieldHeight / 2)
.attr("dy", ".35em")
.text(String);
// fill the table
// select rows
var rows = rowsGrp.selectAll("g.row").data(jsonData);
// create rows
var rowsEnter = rows.enter().append("svg:g")
.attr("class","row")
.attr("transform", function (d, i){
return "translate(0," + (i+1) * (fieldHeight+1) + ")";
});
// select cells
var cells = rows.selectAll("g.cell").data(function(d){return d3.values(d);});
// create cells
var cellsEnter = cells.enter().append("svg:g")
.attr("class", "cell")
.attr("transform", function (d, i){
return "translate(" + i * fieldWidth + ",0)";
});
cellsEnter.append("rect")
.attr("width", fieldWidth-1)
.attr("height", fieldHeight);
cellsEnter.append("text")
.attr("x", fieldWidth / 2)
.attr("y", fieldHeight / 2)
.attr("dy", ".35em")
.text(String);
//update if not in initialisation
if(sortOn !== null) {
// update rows
if(sortOn != previousSort){
rows.sort(function(a,b){return sort(a[sortOn], b[sortOn]);});
previousSort = sortOn;
}
else{
rows.sort(function(a,b){return sort(b[sortOn], a[sortOn]);});
previousSort = null;
}
rows.transition()
.duration(500)
.attr("transform", function (d, i){
return "translate(0," + (i+1) * (fieldHeight+1) + ")";
});
//update cells
rows.selectAll("g.cell").select("text").text(String);
}
我目前无法解决的问题是,排序不太工作。当单击标题时会发生一些事情,但是行没有正确排序。在我看来非常奇怪的是,当检查浏览器中的html元素时,g.w row元素会根据绑定到它们的数据正确排序。
我不认为我的排序函数有问题,因为我在两个表中使用相同的一个。我的猜测是,新排序的行没有提供正确的单元格,但我不知道如何解决这个问题。
编辑:好的,我成功地将单元格中的文本更新为新的排序顺序。更正后的代码在jsfiddle上,也在这里编辑过。但还有一个问题我不明白:
行到新位置的转换与绑定到它们的新排序数据不匹配。例如,当多次点击"id",你就会明白我的意思。我用来转换到新位置的参数"i"是否可能不代表新排序的顺序?我发现了这个例子,它与我的例子相似,并且转换工作正常:
http://examples.oreilly.com/0636920026938/chapter_10/10_delay.html(抱歉,不能发布超过2个链接)
我的代码中的错误在哪里?
找到了我的问题的解决方案:
http://bost.ocks.org/mike/constancy/问题是缺少将数据正确绑定到行的键函数。
通过改变这一行:
var rows = rowsGrp.selectAll("g.row").data(jsonData);
var rows = rowsGrp.selectAll("g.row").data(jsonData,
function(d){ return d.id; });
和在转换后删除单元格更新:
//update cells
rows.selectAll("g.cell").select("text").text(String);
表现在正确排序和转换
相关文章:
- JavaScript数组排序(函数)用于对表行进行排序,而不是排序
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 使用promise和mongoose对文档进行排序
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何更改<svg>标记为<img>用js标记
- Selectize.js:如何对整数值的选项进行排序
- Javascript排序的图像弹出窗口..可以't单独弹出
- 如何通过引用var Using DataTables来进行分页或排序
- 为什么HTML5拖放的目标是孩子?(可排序列表)
- 锚点元素不't使用svg时,请打开EDGE上的href
- 带有填充属性的SVG矩形显示在包含元素的上方插入框阴影
- AngularJs对所有页面中的所有记录进行排序
- 使用onclick绘制SVG路径
- 当属性不一致时,如何根据属性对JS对象列表进行排序
- SVG/JavaScript:尝试选择和更改多边形点
- 跨浏览器d3.js SVG线条渲染日期排序
- 使用d3.js对绑定到svg元素的数据进行排序
- 使用D3/JavaScript在SVG中对动画GIF进行排序,而不停止动画
- D3.js尝试实现可排序的SVG表
- SVG重新排序z索引(Raphael可选)