javascript - D3.js 试图实现可排序的 SVG 表

标签 javascript html d3.js svg

正如我的标题所述,我正在尝试实现一个具有漂亮过渡的交互式表格,这就是我选择 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;});
}

如您所见,单击标题元素时表格会正确排序数据。 基于上表,我开始实现该表的 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.row 元素根据绑定(bind)到它们的数据正确排序。

我认为我的排序函数没有问题,因为我在两个表中使用的是同一个排序函数。 我的猜测是新排序的行没有提供正确的单元格,但我不知道如何解决这个问题。

编辑: 好的,我设法将单元格中的文本正确更新为新的排序顺序。更正后的代码在 jsfiddle 上,也在此处进行了编辑。 但是还有一个问题我就是不明白:

行到新位置的转换与绑定(bind)到它们的新排序数据不匹配。例如,当多次单击“id”时,您会明白我的意思。 我用来转换到新位置的参数“i”是否可能不代表新排序的顺序? 我找到了这个例子,它与我的相似并且转换工作正常:

http://examples.oreilly.com/0636920026938/chapter_10/10_delay.html (抱歉,目前不能发布超过 2 个链接)

我的代码哪里出错了?

最佳答案

在此页面上找到了我的问题的解决方案:

http://bost.ocks.org/mike/constancy/

问题是缺少用于将数据正确绑定(bind)到行的关键函数。

通过改变这一行:

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.js 试图实现可排序的 SVG 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23792791/

相关文章:

asp.net - 在 asp.net 中访问服务器端的输入类型文件

html - 没有 z-index 的堆叠顺序

javascript - 让我们制作一个 map Topojson 没有出现 - 没有错误消息,但什么也没有发生

javascript - 用新的 svg 替换当前的 svg,同时删除旧的 DOM 元素

javascript - 某些 JavaScript 代码存在问题

javascript - Nodejs 中变量作用域的误解

php - PHP 和 JS 变量求值的区别

c# - 删除具有空单元格的表格行c#

javascript - 工具提示的 Mousmove 动画

JavaScript:隐藏字段的真实表单重置