如何更新/重绘多线图?

时间:2016-12-15 17:00:18

标签: d3.js

我正在制作一个图表,在时间线上显示不同类型的医疗事件,每个“跟踪”事件(药物,实验室和成像)与(红色)线相连。 (注意底部轨道“其他”故意没有线。)

enter image description here

使用:

渲染它们(在Typescript中)
lineGen = d3.svg.line()
.x((d:PatientEvent) => timeScaleAbs(d.time))
.y((d:PatientEvent) => ordScaleTmln(d.type) + ordScaleTmln.rangeBand()/2);

clipAreaGroup.append('path')
    .attr('d', lineGen(data.filter((val:PatientEvent) => {return val.type == 'Med'})))
    .classed('event-group-line', true);
clipAreaGroup.append('path')
    .attr('d', lineGen(data.filter((val:PatientEvent) => {return val.type == 'Lab'})))
    .classed('event-group-line', true);
clipAreaGroup.append('path')
    .attr('d', lineGen(data.filter((val:PatientEvent) => {return val.type == 'Img'})))
    .classed('event-group-line', true);

图表顶部有一个导航画笔,但我不知道如何正确编写代码以在刷子事件后更新每个行路径。我已经尝试将下面的代码混合在一起(除了添加.data()行之外,它几乎与上面的代码相同)并且它几乎可以工作,除了顶行(用于Medication事件)不会重绘(在刷子选择完成后如下所示。)

lineGen = d3.svg.line()
    .x((d:PatientEvent) => timeScaleAbs(d.time))
    .y((d:PatientEvent) => ordScaleTmln(d.type) + ordScaleTmln.rangeBand()/2);

clipAreaGroup.selectAll('path')
    .data(data.filter((val:PatientEvent) => {return val.type == 'Med'}))
    .attr('d', lineGen(data.filter((val:PatientEvent) => {return val.type == 'Med'})))
    .classed('event-group-line', true);
clipAreaGroup.selectAll('path')
    .data(data.filter((val:PatientEvent) => {return val.type == 'Lab'}))
    .attr('d', lineGen(data.filter((val:PatientEvent) => {return val.type == 'Lab'})))
    .classed('event-group-line', true);
clipAreaGroup.selectAll('path')
    .data(data.filter((val:PatientEvent) => {return val.type == 'Img'}))
    .attr('d', lineGen(data.filter((val:PatientEvent) => {return val.type == 'Img'})))
    .classed('event-group-line', true);

enter image description here

这似乎与调用的顺序有关。当我重新安排它们并打电话给“Img”时 - > “Med” - > “Lab”,然后只有“Lab”行会重绘。

我知道我不是非常优雅地做这件事,但我真的不明白d3如何跟踪哪些行是为了更新目的。我得到了重绘的点,但线条路径确实让我很困惑。

1 个答案:

答案 0 :(得分:2)

当您致电clipAreaGroup.append('path')时,您正在<path>内创建新的<svg>。你这样做了三次,所以你的<path>最终会有三个<svg>

当您致电clipAreaGroup.selectAll('path').data(...)时,您告诉d3选择每个<path>,然后您将过滤后数据中的每个数据绑定到选择中的元素(创建新<path> s任何额外的数据)。您这样做了三次,每次根据该调用的过滤数据更新d值,这就是您排列它们的顺序正在改变输出的原因。

您可以通过多种方式处理更新行,但最简单的方法可能是避免数据绑定并只存储您创建的<path>

var medPath = clipAreaGroup.append('path')
  .attr('d', lineGen(data.filter((val:PatientEvent) => {return val.type == 'Med'})))
  .classed('event-group-line', true);

然后,当您想要更新该路径时,只需更新其d attr:

medPath.attr('d', lineGen(data.filter((val:PatientEvent) => {return val.type == 'Med'})))