Message Boards Message Boards

Scaling Dynamic widgets up

GROUPS:

cross posted in mathematica.stackexchange

Problem

The serious flaw of Dynamic is a combination of facts:

  • it is triggered/refreshed by any kind of mutation of a symbol,

  • careful, with respect to evaluation, metaprogramming/construction of symbols is really cumbersome

An example is worth a thousand words so:

{ Dynamic@x[[1]], Dynamic@x[[2]]}

You can't trigger one without other one being affected even if the value didn't change. And writing:

{ Dynamic @ x1, Dynamic @ x2 }

will be tough to automatically scale/maintain for regular users. A real world example can be found here:

https://mathematica.stackexchange.com/q/128344/5478

The code in the answer is not something you'd love to write on daily basis:

DynamicModule[{}, Graphics[{
   ( ToExpression[
      "{sA:=state" <> ToString[#] <> ", sB:=state" <> ToString[#2] <> "}",
      StandardForm, 
      Hold
    ] /. Hold[spec_] :> With[spec, 
       {  Dynamic @ If[TrueQ[sA || sB], Red, Black], 
          Line[{pts[#1], pts[#2]}]
       }
    ]
   ) & @@@ edges
   ,
   PointSize[0.025],
   (
    ToExpression[
      "{sA:=state" <> ToString[#] <> "}", 
      StandardForm, 
      Hold
    ] /. Hold[spec_] :> With[spec, 
       { Dynamic @ If[TrueQ[sA], Red, Black], 
         EventHandler[ Point @ pts[#], 
           {"MouseEntered" :> (sA = True), "MouseExited" :> (sA = False)}
         ]
       }
    ]
   ) & /@ names
  }, 
  ImageSize -> Large]
 ]

Very often a smart, specific solution can be applied but it would be nice to be able to do mindless things and not be limited by syntax/design issues but real limitations of how much FrontEnd can handle.

What can we do to make programming of idioms presented in the linked question more approachable?

Solution

Among features that will come, DynamicObjecs` package provides FrontEndSymbol/FrontEndModule utilities which can be used to solve this problem.

It is not a golden hammer and needs understanding of what is going on under the hood but can be used in powerful ways. So I strongly recommend reading wiki before creating own examples:

https://github.com/kubaPod/DynamicObjects/wiki/FrontEndModule-and-FrontEndSymbol

TL;DR;

Follow installation steps from https://github.com/kubaPod/DynamicObjects

Then the code from the linked topic can be rewritten to:

Needs @ "DynamicObjects`";

n = 120;
names = Range[n];
pts = AssociationThread[names -> N@CirclePoints[n]];
edges = RandomSample[Subsets[names, {2}], 250];


FrontEndModule[ 
  Graphics[
    { 
      { 
        Dynamic @ If[ 
          TrueQ[ FrontEndSymbol["state",#1] || FrontEndSymbol["state", #2] ]
        , Red
        , Black
        ]
      , Line[{pts[#1],pts[#2]}]
      }& @@@ edges    
    , {
        AbsolutePointSize@7
      , Dynamic @ If[ TrueQ[FrontEndSymbol["state",#1]], Red, Black]
      , EventHandler[Point@pts[#]
        , { "MouseEntered":>(FrontEndSymbol["state",#1]=True)
          , "MouseExited":>(FrontEndSymbol["state",#1]=False)
          }
        ]
      }& /@ names
    }
  , ImageSize -> Medium
  ]
]

enter image description here

Much cleaner, isn't it?

POSTED BY: Kuba Podkalicki
Answer
13 days ago

Much thx!

POSTED BY: Mitch Stonehocker
Answer
13 days ago

Group Abstract Group Abstract