Giter Site home page Giter Site logo

Comments (12)

Tao-VanJS avatar Tao-VanJS commented on August 24, 2024 2
van.derive(() => {
  if (sigmaInstanceAvailable.val)
    sigmaInstance.setSetting("labelSize", settings.labelSize.value.val)
});

Alternatively, you can make sigmaInstance a State object. Then you can simply have:

van.derive(() => {
  sigmaInstance.val?.setSetting("labelSize", settings.labelSize.value.val)
})

from van.

Tao-VanJS avatar Tao-VanJS commented on August 24, 2024 1

Ah..., I see.

For the derivation here:

  van.derive(() => {
    // Without this line: settings.scalingRatio.value.val;
    if (layout)
      layout.settings.scalingRatio = logslider(settings.scalingRatio.value.val);
  });

layout needs to be set when van.derive is being called. Otherwise, settings.scalingRatio.value.val won't be read, thus settings.scalingRatio.value won't be registered as a dependency of the derivation.

from van.

nbonfils avatar nbonfils commented on August 24, 2024 1

Thank you very much for taking the time to explain it to me!
Closing the issue since it's not a bug.

And I don't know if it's of interest to you to see where van is used, but here is the project that we are going to release in the coming weeks:
https://github.com/nbonfils/bibliograph2

We switched from Alpine to Van and I am not looking back, it's honestly a great framework when you don't want to deal with the absurd complexity of everything else out there!

from van.

Tao-VanJS avatar Tao-VanJS commented on August 24, 2024

I think the line:

layout.settings.scalingRatio = logslider(layout.settings.scalingRatio.value.val)

is problematic.

Let's break down what this line does:

  1. Read the val property of the State object (let's name this State object s1) pointed by layout.settings.scalingRatio.value. By reading the val property, you're registering s1 as a dependency of the derivation.
  2. Call function logslider, which will create a new scalingRatio object, since the State object is in its value property, I assume a new State object will be created along the way (let's name this State object s2).

Thus, the end result is, you're registering s1 as the dependency of the derivation, but s1 might no longer be activity in your program (s2 is the one being actively used). In reality, if s1 is not being actively used, the dependency of it will subject to GC, whose behavior is subject to VanJS's internal implementation.

from van.

sirenkovladd avatar sirenkovladd commented on August 24, 2024

https://jsfiddle.net/jsg0ukqv/1/

@nbonfils, сould you please give more context, I have not been able to reproduce the error

from van.

nbonfils avatar nbonfils commented on August 24, 2024

Thank you both for your quick replies!

@Tao-VanJS Actually the line is:

layout.settings.scalingRatio = logslider(settings.scalingRatio.value.val);

We could even simplify it as:

layout.settings.scalingRatio = settings.scalingRatio.value.val;

So layout and settings are two different object, I tried renaming settings to config but to no avail as well.

@sirenkovladd That example looks pretty much like what I have, tomorrow I'll push it on a repo so I can share the full context of this code. In the meantime here is the full file:
https://0x0.st/XpiX.js

As you can see I am currently working around the issue by doing this:

// Some code above ...

  let layout;
  let sigmaInstance;
  van.derive(() => {
    if (!graph.val) return;
    if (layout) layout.kill();
    layout = new FA2Layout(graph.val, {
      settings: {
        gravity: logslider(settings.gravity.value.rawVal),
        scalingRatio: logslider(settings.scalingRatio.value.rawVal),
      },
    });
    if (sigmaInstance) sigmaInstance.kill();
    sigmaInstance = new Sigma(graph.val, sigmaContainer, {
      itemSizesReference: "positions",
      zoomToSizeRatioFunction: (x) => x,
    });
    layout.start();
    layoutRunning.val = true;
  });

// More code in-between ...

  const settings = {
    scalingRatio: {
      value: van.state(70),
      min: 0,
      max: 100,
      label: "Scaling (overall graph size)",
    },
    gravity: {
      value: van.state(20),
      min: 0,
      max: 100,
      label: "Gravity (graph compactness)",
    },
    labelSize: {
      value: van.state(14),
      min: 0,
      max: 100,
      label: "Label size",
    },
    labelDensity: {
      value: van.state(1),
      min: 0,
      max: 10,
      label: "Label density",
    },
    labelRenderThreshold: {
      value: van.state(6),
      min: 0,
      max: 10,
      label: "Label render threshold",
    },
    nodeScale: {
      value: van.state(100),
      min: 1,
      max: 200,
      label: "Node scale",
    },
  };

  van.derive(() => {
    settings.scalingRatio.value.val;
    if (layout)
      layout.settings.scalingRatio = logslider(settings.scalingRatio.value.val);
  });
  van.derive(() => {
    settings.gravity.value.val;
    if (layout) layout.settings.gravity = logslider(settings.gravity.value.val);
  });
  van.derive(() => {
    settings.labelSize.value.val;
    sigmaInstance?.setSetting("labelSize", settings.labelSize.value.val);
  });
  van.derive(() => {
    settings.labelDensity.value.val;
    sigmaInstance?.setSetting("labelDensity", settings.labelDensity.value.val);
  });
  van.derive(() => {
    settings.labelRenderThreshold.value.val;
    sigmaInstance?.setSetting(
      "labelRenderedSizeThreshold",
      settings.labelRenderThreshold.value.val,
    );
  });
  van.derive(() => {
    settings.nodeScale.value.val;
    graph.rawVal?.forEachNode((nodeRef, attr) =>
      graph.rawVal.mergeNodeAttributes(nodeRef, {
        size: attr.origSize * (settings.nodeScale.value.val / 100),
      }),
    );
  });

// Even more code below ...

Each of those derive statement don't run without the explicit val access from the state.

from van.

nbonfils avatar nbonfils commented on August 24, 2024

Yes, so layout is undefined initially, but then once layout is defined and I move the slider that changes settings.scalingRatio.value.val the derivation is called only when the first line is uncommented, if I change my code to reflect your example, then the derivation is never called. That's exactly what is having me puzzled.

from van.

Tao-VanJS avatar Tao-VanJS commented on August 24, 2024

Let's take a look at the example below:

let layout = undefined;

van.derive(() => {
  // Without this line: settings.scalingRatio.value.val;
  if (layout)
    layout.settings.scalingRatio = logslider(settings.scalingRatio.value.val);
});

When van.derive is called. The "then clause" of the if statement is not called. As a result, settings.scalingRatio.value.val is not accessed, thus the state settings.scalingRatio.value is not registered as a dependency of the derivation. Future changes of settings.scalingRatio.value will not trigger the derivation.

If the code is like that:

let layout = undefined;

van.derive(() => {
  settings.scalingRatio.value.val;
  if (layout)
    layout.settings.scalingRatio = logslider(settings.scalingRatio.value.val);
});

settings.scalingRatio.value.val is accessed explicitly in the first line of derivation, thus settings.scalingRatio.value is registered as a dependency of derivation in this implementation.

from van.

nbonfils avatar nbonfils commented on August 24, 2024

Ahh that makes sense thank you for this explaination!

But what about this other case:

van.derive(() => {
    // settings.labelSize.value.val;
    sigmaInstance?.setSetting("labelSize", settings.labelSize.value.val);
  });

With settings.labelSize.value.val; commented out, this derive statement doesn't trigger when settings.labelSize.value.val changes. Why is that the case here?

Forgive me if I missed this in the docs but does the "registration" occur when the function inside the van.derive statement runs for the first time?

from van.

Tao-VanJS avatar Tao-VanJS commented on August 24, 2024
sigmaInstance?.setSetting("labelSize", settings.labelSize.value.val)

is just the syntax sugar of

if (sigmaInstance)
  sigmaInstance.setSetting("labelSize", settings.labelSize.value.val)

Every time when the derivation function is called, all the states accessed in the derivation will be registered as the dependencies of derivation. When any of the dependency states changes, the derivation will be triggered, and a new set of dependencies will be registered upon the execution of the derivation.

I think the example in this section illustrates the mechanism well.

from van.

nbonfils avatar nbonfils commented on August 24, 2024

Got it! So the derive statement not triggering stems from the fact that that sigmaInstance is not a state, therefore not registered and won't retrigger the derive statement when it changes and is available, thus never registering settings.labelSize.value.val.

Am I understanding this correctly?

So another way to go about this would be to have another state, let's call it sigmaInstanceAvailable and do the following:

van.derive(() => {
  if (sigmaInstanceAvailable.val)
    sigmaInstance.setSetting("labelSize", settings.labelSize.value.val)
});

from van.

sirenkovladd avatar sirenkovladd commented on August 24, 2024

Yes, that would be a very nice optimized code

from van.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.