Skip to content

updating in place? #1022

Open
Open
@Fil

Description

@Fil

If we want to update the marks in place in the DOM rather than throw them away and create a new one on each tick (in the context of the time animations, and later interactions), we can pass the previous node as part of the context (as in the patch below), and use join rather than append.

(And then, why not go further and always pass a g element, on any call to render — that is, independently of whether it's a previously rendered node or a new one just created with create("svg:g", context)? The mark would still be free to ignore it and return something else, of course.)

diff --git a/src/marks/dot.js b/src/marks/dot.js
index e4140b55..3442267f 100644
--- a/src/marks/dot.js
+++ b/src/marks/dot.js
@@ -1,4 +1,4 @@
-import {path, symbolCircle} from "d3";
+import {path, select, symbolCircle} from "d3";
 import {create} from "../context.js";
 import {positive} from "../defined.js";
 import {identity, maybeFrameAnchor, maybeNumberChannel, maybeTuple} from "../options.js";
@@ -55,13 +55,12 @@ export class Dot extends Mark {
     const {x: X, y: Y, r: R, rotate: A, symbol: S} = channels;
     const [cx, cy] = applyFrameAnchor(this, dimensions);
     const circle = this.symbol === symbolCircle;
-    return create("svg:g", context)
+    return (context.node ? select(context.node) : create("svg:g", context)
         .call(applyIndirectStyles, this, scales, dimensions)
-        .call(applyTransform, this, scales)
-        .call(g => g.selectAll()
+        .call(applyTransform, this, scales))
+        .call(g => g.selectAll(circle ? "circle" : "path")
           .data(index, i => i)
-          .enter()
-          .append(circle ? "circle" : "path")
+          .join(circle ? "circle" : "path")
             .call(applyDirectStyles, this)
             .call(circle
               ? selection => {
diff --git a/src/plot.js b/src/plot.js
index 51864c40..6a9ec847 100644
--- a/src/plot.js
+++ b/src/plot.js
@@ -376,7 +376,7 @@ export function plot(options = {}) {
           }
           const ifacet = [...facet.filter(i => T[i] < time1), ...(currentTime < time1) ? Ii : [], ...facet.filter(i => T[i] >= time1)];
           const index = mark.timeFilter(ifacet, T, currentTime);
-          timeNode = mark.render(index, scales, interp, dimensions, context);
+          timeNode = mark.render(index, scales, interp, dimensions, {...context, node: timeMark.node});
         } else {
           // here typically t = 0;
           const index = mark.timeFilter(facet, T, currentTime);

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions