Skip to main content

Release notes *2.7.6*

· 4 min read

✨ Highlights

  • 🔧 More Control Over Manipulate
  • 📊 Expanded Plotly API Full access to Plotly's update methods:
    • Allows precise control over visual elements (e.g. opacity, color).
    • Enables dynamic updates using event handlers like sliders.
  • 🎞️ Improved GUI for Animate
  • 🌐 Improved Dynamic HTML Export (Live Demo) Full demo available here: LiveHTML Demo. Exporting widgets with Manipulate/Animate to HTML is now much more practical and feature-rich.
  • We disabled automatic updates
Download original notebook

More control over Manipulate

You can specify when to update the expression after or during user's action

Manipulate[Column[{
  Style[StringTemplate["`` m/s"][x], Blue],
  Table["🚗", {i, Floor[x/25]}]//Row 
}], {x,10,100}, (*BB[*)(ContinuousAction->True)(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRAeB5AILqnMSXXKr0hjgskHleakFnMBGU6JydnpRfmleSlpzDDlQe5Ozvk5+UVFDGDwwR6dwcAAAAHdFiw="*)(*]BB*)] // Quiet
(*GB[*){{(*VB[*)(EventObject[<|"Id" -> "859d0076-5a64-4177-9850-24cc06474b21", "Initial" -> {55.}, "View" -> "576e67c2-30db-4f71-a964-61c65ce843a9"|>])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKm5qbpZqZJxvpGhukJOmapJkb6iZampnomhkmm5kmp1qYGCdaAgB9HhVR"*)(*]VB*)}(*||*),(*||*){(*VB[*)(FrontEndRef["90083ee4-1dd3-445d-bbcd-b93516befe83"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKWxoYWBinpproGqakGOuamJim6CYlJQMJS2NTQ7Ok1LRUC2MAhNYWBA=="*)(*]VB*)}}(*]GB*)

Expanded API for Plotly

We fully exposed the available methods to update your Plotly graphs

p = Plotly[<|"type"->"line", "y"->{1,2,3,4,5,6}|>]

EventHandler[InputRange[0,1,0.1,1.0], (PlotlyRestyle[p, <|"opacity"->#, "marker.color"->"red"|>])&]
(*VB[*)(FrontEndRef["2ccca95f-4a5f-4859-84b0-abdef4e9f593"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKGyUnJydamqbpmiSCCAtTS10LkyQD3cSklNQ0k1TLNFNLYwCR8xZG"*)(*]VB*)
(*VB[*)(EventObject[<|"Id" -> "29af7c92-67e5-4dfc-8167-1fd9a95adc3c", "Initial" -> 1., "View" -> "9fbf4db9-7a1f-40af-bc5f-c8d9f7ad0234"|>])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKW6YlpZmkJFnqmicapumaGCSm6SYlm6bpJlukWKaZJ6YYGBmbAACcGBaa"*)(*]VB*)

GUI for Animate

We upgraded Animate

Animate[Series[Cos[x], {x,0,n}], {n,2, 10, 1}, AnimationRate->3]
(*VB[*)(FrontEndRef["d8266190-9a0e-4e5b-aa21-0aecf09081e2"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp1gYmZkZWhroWiYapOqapJom6SYmGhnqGiSmJqcZWBpYGKYaAQCAJRWT"*)(*]VB*)

Dynamic HTML Export

Check it out!

Here is a full demo

IDW interpolation with categorical partitioning

Motivation

When you are trying to export a widget with continuously changing input data (it can be a canvas with a pointer or an input range with fine steps), it becomes cumbersome and inefficient to manually sample all possible positions of them.

Imagine a Gaussian distribution controlled by a mouse. How can this be exported to HTML? For each mouse position, you have to recalculate the Gaussian. This is done by the WL kernel and not the JavaScript frontend.

udata = {{-1,0}, {1,0}};

Graphics[{
  Cyan, Line[udata // Offload], Red, PointSize[0.05],
  EventHandler[Point[{0,0.5}], {
    "drag" -> ((udata = generate[#, 0.1])&)
  }]
}, PlotRange->{{-1,1}, {0,1}}, ImagePadding->None, Axes->{True, False}, ImageSize->Small]

ClearAll[generate];
generate[{x_, y_}, k_] := Table[{t, y Exp[- (*FB[*)(((*SpB[*)Power[(x - t)(*|*),(*|*)2](*]SpB*))(*,*)/(*,*)(2 k))(*]FB*)]}, {t,-1,1, 0.03}]
(*VB[*)(Graphics[{RGBColor[0, 1, 1], Line[Offload[udata]], RGBColor[1, 0, 0], PointSize[0.05], EventListener[Point[{0, 0.5}], {"drag" -> "87be2e86-95dd-4e22-9134-cb9a41ec6daa"}]}, PlotRange -> {{-1, 1}, {0, 1}}, ImagePadding -> None, Axes -> {True, False}, ImageSize -> Small])(*,*)(*"1:eJxtUFtOwzAQdIEKKsEhkPjNR0MozVcFCApSBVXCBTbxOlhybWQnCHETuAG34ibghyyawH6MZh8zGu1xpQo2IoSYPQu3SlA2dt2BhaWG5ydemzBx+xU3LduN+2J5eaWE0txywkcRfu1WXGLo9i08MCYUUOPcOgot/OPkTUiEoJ1YWCsu25K/of54d/W5YDtud2Th+gVl65KhRB0k4ygJVzG6N9XE19diO6fZuiw6gaUjVENTnlgyP68wxfksyc8oTTJM0ySfnmZJXeWQTbGeUYC+PoQWqi1ANthPMcj0bSv87W/Wwdw7H1pyt4EG10Apl43f3CuJgztHLl7R9G09edQd+h/dgDBD3ST6u3f7q3IDQvwAMSp2ew=="*)(*]VB*)

Try to drag a red dot if you are reading it from the wljs blog page

Solution

Quite often, we do not need all possible points to be sampled, but only the randomly scattered probe points, which are practical to obtain. The rest can be interpolated using a general Inverse Distance Weighting (IDW) in continuous feature space. Non-numerical data such as checkboxes and select boxes can be treated as categorical types.

What about the output? It can be:

  • Number
  • Array (List)
  • Tensor
  • String
  • Other expressions

The first three can easily be interpolated, while for strings and other expressions, we can pick the closest one from an N-dimensional space.

More about a string type

However, we went deeper. Look at this example.

Manipulate[Style[StringTemplate["`` m/s"][x], Blue], {x,10,100}, ContinuousAction->True] // Quiet
(*GB[*){{(*VB[*)(EventObject[<|"Id" -> "1a55b5d2-6aef-4761-9d22-12bb46ecea26", "Initial" -> {55.}, "View" -> "cb8b1804-0e26-4255-9310-b9fce1b0860e"|>])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJydZJBlaGJjoGqQamemaGJma6loaGxroJlmmJacaJhlYmBmkAgB7YRU4"*)(*]VB*)}(*||*),(*||*){(*VB[*)(FrontEndRef["c2acc47b-2c38-4311-aa65-0833de072324"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJxslJiebmCfpGiUbW+iaGBsa6iYmmpnqGlgYG6ekGpgbGRuZAACGCRUr"*)(*]VB*)}}(*]GB*)

The output result is a string, but quite predictable. We analyze all strings used in outputs and decompose them into numbers and string templates if possible. Then the numerical content is interpoalted as usual and the final string is composed back.

Better handling external windows

You can assign handlers to the events generated by projected cells

state = "";
TextView[state // Offload, "Label"->"State"]

cell = CellPrint[Plot[x,{x,0,1}], "Target"->_];
EventHandler[cell, {
	"Mounted" -> Function[Null, state = "Mounted"],
	"Closed" -> Function[Null, state = "Closed"]
}]
(*VB[*)(FrontEndRef["ed11ea2a-b91d-4a22-9a7e-eb547d1a1073"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp6YYGqYmGiXqJlkapuiaJBoZ6VommqfqpiaZmpinGCYaGpgbAwCRzxXu"*)(*]VB*)

And manually close it if needed

Delete[cell]

Note that Mounted event contains WindowObj, which can be used together with FrontSubmit and FrontFetch to trigger actions there.

Let expression

We adopted Leonid Shifrin's library LetWL

Leonid Shifrin is a software developer (Wolfram Research), an enthusiast, and the author of the excellent work Mathematica Programming: An Advanced Introduction by Leonid Shifrin. Please read it here if you haven't!

Let[{a = 1, b = a * 2},
  b
]
2

Code Freeze

We decided to disable automatic granular updates by default (except for the entire WLJS Notebook app), unless you explicitly request it from the launcher window.

We do not expect a demand for frequent updates, as our project is becoming more and more stable. We do this for your own safety, ensuring that you won't face a situation where there is a version mismatch between different subsystems. Additionally, it reduces loading time because it does not check versions by default.