D3.js 尝试实现可排序的 SVG 表

2023-11-23

正如我的标题所述,我正在尝试实现一个具有良好过渡的交互式表格,这就是我选择 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 元素根据绑定到它们的数据正确排序。

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

EDIT:好的,我设法将单元格中的文本正确更新为新的排序顺序。更正后的代码位于 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);

to

var rows = rowsGrp.selectAll("g.row").data(jsonData, 
    function(d){ return d.id; });

并在转换后删除单元格更新:

//update cells
rows.selectAll("g.cell").select("text").text(String);

该表现在可以正确排序和转换。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

D3.js 尝试实现可排序的 SVG 表 的相关文章

  • 平均分配固定大小容器的空间。 Flexbox 的案例?

    如何设计 HTML CSS 结构 将固定大小的容器水平分成三部分 第一部分的高度应与其内容需求一样高 第二部分和第三部分将共享剩余的空间五五十 无论它们的内容如何 如果其内容的大小超过此限制 则该部分应该是可滚动的 它的 HTML 部分很简
  • 无需重定向的 HTML 页面提交

    有没有什么方法可以在不使用ajax的情况下提交html表单而无需从当前页面重定向 你可以设置一个target 为您form 这样您就可以将表单提交到新选项卡 target blank 或一个小的 隐藏的iframe target nameo
  • 保证金如何运作?

    我在下面提供了marginfix这是一个块级元素并且one and two也是块级的 但它们是浮动的 这就是为什么它们位于同一行布局的原因 但是marginfix也不浮动 块级元素应位于该元素下方 如下所示
  • 仅从功能区打开一个对话框

    我有一个带有登录按钮的功能区 可打开登录对话框 我想将对话框的数量限制为一个 我正在使用函数 displayDialogAsync startAddress options callback https learn microsoft co
  • 替换img路径jquery

    我正在尝试替换 jquery 中的 img 路径 注入远程页面 replaceexample com thumbs withexample com images 我已经尝试过这个 但似乎不起作用 img attr src replace t
  • 为什么Promise中的代码会同步执行? [复制]

    这个问题在这里已经有答案了 在我的项目中 我有一个很长时间运行的操作 所以我决定将其放入Promise因为我认为这样我就可以在里面的代码继续执行其他操作Promise正在跑步 调试的时候发现外面的代码Promise仅当里面的代码执行Prom
  • 在已标记的输入元素上使用“aria-labelledby”的目的是什么?

    许多 ARIA 演示网站使用以下代码
  • CSS 过滤器在 Firefox 中不起作用

    我正在尝试 CSS 过滤器 但它在我的 Firefox 15 0 浏览器中不起作用 HTML div class google img src https www google com images srpr logo3w png div
  • NodeJS - 将相对路径转换为绝对路径

    In my 文件系统我的工作目录在这里 C temp a b c d 在 b bb 下有文件 tmp txt C temp a b bb tmp txt 如果我想从工作目录转到该文件 我将使用以下路径 bb tmp txt 如果该文件不存在
  • 如何将React JS状态保存到本地存储中

    我不知道如何将 React js 状态存储到本地存储中 import React Component from react import App css import auth createUserProfileDocument from
  • 如何跨多个 React Redux 组件使用 requestAnimationFrame 实现游戏循环?

    努力思考最好的解决办法 我可以使用递归调用requestAnimationFrame有一个游戏循环 export interface Props name string points number onIncrement gt void o
  • 使用 eval 时不会受到 XSS 威胁

    我正在制作 不是现在 但我仍然对这个感到好奇 一款使用 HTML5 和 JS 的游戏 我想要的是人们可以插入自定义脚本 但要安全 function executeCustomJS code eval code bad 当然这段代码非常糟糕
  • 浮动CSS属性导致父div不继承高度?

    我在 div 中有一个元素设置为float right但是 它会导致最外面的 div 不环绕 这是jsfiddle http jsfiddle net W792X 5 for it 我试图让提交按钮在 div 内浮动 但设置该属性似乎会导致
  • Firebase 身份验证和实时应用程序数据库如何保护自身安全?

    从一般开发的角度来看 我很好奇如何保护在线资源的访问 我们使用以下 Firebase 配置参数初始化 Web 应用程序 apikey authdomain projectid databaseurl messagesenderid 服务器如
  • jQuery UI 对话框 - 关闭后无法打开

    我有一个问题jquery ui dialog box https jqueryui com dialog 问题是 当我关闭对话框然后单击触发它的链接时 除非刷新页面 否则它不会再次弹出 如何在不刷新实际页面的情况下回调对话框 下面是我的代码
  • eventSources 到事件 Json,完整日历

    我正在尝试从 eventSources 获取 json 调用到我的事件 我在 eventSources 中返回的 json 是 title Title Test start 1305841052 当我将此字符串传递到事件中时 它会正确显示日
  • 如何得知客户端从服务器的下载速度?

    根据客户的下载速度 我想以低质量或高质量显示视频 任何 Javascript 或 C 解决方案都是可以接受的 Thanks 没有任何办法可以确定 您只能测量向客户端发送数据的速度 如果没有来自客户端的任何类型的输入来表明其获取信息的速度 您
  • 有序 JSON 对象

    我有一个 servlet 它与数据库通信 然后返回有序 按时间排序 对象的列表 在servlet部分 我有 access DB returns a list of User objects ordered ArrayList users M
  • Radiobutton-带有纯 html/css 的按钮

    是否可以创建像这样的单选按钮JQuery http jqueryui com demos button radio那些 用纯html css thanks 试试这个小提琴 http jsfiddle net mcXm7 1 http jsf
  • YouTube 点击时禁用 HTML5

    有没有办法让我们通过javascript禁用HTML5视频的 播放 暂停 点击全屏 功能 然后在我们再次需要时将其放回去 我不知道你是否可以禁用它们 但你可以使用 css 删除它们 video webkit media controls f

随机推荐