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.