Skip to main content

Release notes *2.7.4*

ยท 3 min read

๐Ÿ‘ Open Source Support

  • Now on Open Collective! Support and engage with the project: Join us here.

๐Ÿ“Š Plotting Improvements

  • Log plots fixed: LogPlot and LogLogPlot now scale correctly.
  • New ImageSizeRaw support: Precisely overlay raster and vector graphics with pixel-perfect control.

๐Ÿงฑ Dataset Overhaul

  • Major upgrade to Dataset supportโ€”now handles nested structures, symbolic keys, Entity, Quantity, and more.

๐Ÿ–ผ๏ธ UI & Usability

  • Added โ€œInsert Cell Beforeโ€ button (based on GitHub feedback).
  • Extended MMAView: Native-style interactive 3D plots, Manipulate, Animate, and even ListAnimate now supported seamlessly.

๐ŸŒ Web & API Enhancements

  • Simplified REST API with a JavaScript helper classโ€”build custom notebook interfaces in minutes.
  • MDX/React integration: Embed cells or full notebooks into blogs and React apps. See it in action here.
Download original notebook

const balloonContainer = document.getElementById("balloon-container");

function random(num) {
  return Math.floor(Math.random() * num);
}

function getRandomStyles() {
  var r = random(255);
  var g = random(255);
  var b = random(255);
  var mt = random(200);
  var ml = random(50);
  var dur = random(5) + 5;
  return `
  background-color: rgba(${r},${g},${b},0.7);
  color: rgba(${r},${g},${b},0.7); 
  box-shadow: inset -7px -3px 10px rgba(${r - 10},${g - 10},${b - 10},0.7);
  margin: ${mt}px 0 0 ${ml}px;
  animation: float ${dur}s ease-in infinite
  `;
}

function createBalloons(num) {
  for (var i = num; i > 0; i--) {
    var balloon = document.createElement("div");
    balloon.className = "balloon";
    balloon.style.cssText = getRandomStyles();
    balloonContainer.append(balloon);
  }
}

function removeBalloons() {
  balloonContainer.style.opacity = 0;
  setTimeout(() => {
    balloonContainer.remove()
  }, 500)
}

createBalloons(10);
setTimeout(removeBalloons, 15000);

return '';

Open-Source Communityโ€‹

We joined Open Collective ๐ŸŽˆ

WLJS Notebook - Open Collective

Let's dive into release notes

Log plotsโ€‹

We fixed scaling issues with LogPlot and LogLogPlot

LogPlot[(*SpB[*)Power[x(*|*),(*|*)2](*]SpB*), {x,0,1}]
(*VB[*)(FrontEndRef["2ada88d8-e525-4c55-bfbd-d08aab31a0cc"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKGyWmJFpYpFjoppoameqaJJua6ialJaXophhYJCYmGRsmGiQnAwCQsBaC"*)(*]VB*)

ImageSizeRawโ€‹

A new option of Graphics is supported to make it easier to overlay raster graphics with lines and user primitives. The major differences compared to ImageSize are:

  • It considers the pixel density ratio of the screen.
  • It guarantees that the canvas size will match exactly with ImageSizeRaw.

For example, it allows for creating complex plots that combine Image and Graphics using Inset:


some interpolated data

fmo = { (*VB[*)(Get[FileNameJoin[{".iconized", "None-b5c.wl"}]])(*,*)(*"1:eJxTTMoPSmNhYGAo5gUSYZmp5S6pyflFiSX5RcEcQBHP5Py8zKrUlMyMI0wMaUwghSDVQaU5qcGsQIZPYlJqTjBIyC8/LxVNAYjhlpmTChYJKSpNBQDEQxmP"*)(*]VB*),  (*VB[*)(Get[FileNameJoin[{".iconized", "None-96e.wl"}]])(*,*)(*"1:eJxTTMoPSmNhYGAo5gUSYZmp5S6pyflFiSX5RcEcQBHP5Py8zKrUlMyMI0wMaUwghSDVQaU5qcGsQIZPYlJqTjBIyC8/LxVNAYjhlpmTChYJKSpNBQDEQxmP"*)(*]VB*)};
With[{f1 = (*VB[*)(Get[FileNameJoin[{".iconized", "None-b5c.wl"}]])(*,*)(*"1:eJxTTMoPSmNhYGAo5gUSYZmp5S6pyflFiSX5RcEcQBHP5Py8zKrUlMyMI0wMaUwghSDVQaU5qcGsQIZPYlJqTjBIyC8/LxVNAYjhlpmTChYJKSpNBQDEQxmP"*)(*]VB*), f2 = (*VB[*)(Get[FileNameJoin[{".iconized", "None-96e.wl"}]])(*,*)(*"1:eJxTTMoPSmNhYGAo5gUSYZmp5S6pyflFiSX5RcEcQBHP5Py8zKrUlMyMI0wMaUwghSDVQaU5qcGsQIZPYlJqTjBIyC8/LxVNAYjhlpmTChYJKSpNBQDEQxmP"*)(*]VB*)}, NumericArray[255.0 Table[
  Clip[{f1[{x,y}], 0, f2[{x,y}]}/100.0, {0,1}]
, {y, 0, 5.0, 0.02}, {x, 10, 120, 0.3}] // Reverse
, "UnsignedInteger8", "ClipAndRound"]];
imgWide = Image[%, "Byte"];

overlay it with vector graphics

Graphics[{
  Inset[imgWide, {Mean[{10,120}], Mean[{1,5}]}]
}, 
  PlotRange->{{10,120}, {1,5}}, 
  Frame->True, Axes->True, 
  ImageSizeRaw->ImageDimensions[imgWide],
  FrameTicksStyle->Directive[FontSize->14],
  FrameStyle->Directive[FontSize->14],
  FrameLabel->{"wavenumber (cm^{-1})", "H (T)"},
  Epilog->{White, AbsoluteDashing[{4}], 
    Line[Table[{41.6 + 0.035 x, x}, {x,0,5}]],
    Line[Table[{41.6 - 0.092 x, x}, {x,0,5}]],
    Line[Table[{89.0 + 0.466 1.97 x, x}, {x,0,5}]],
    Line[Table[{89.0 - 0.466 1.90 x, x}, {x,0,5}]],
    Line[Table[{112.6 + 0.466 2.26 x, x}, {x,0,5}]],
    Line[Table[{112.6 - 0.466 2.39 x, x}, {x,0,5}]]
  }
]
(*VB[*)(FrontEndRef["ff318b33-3e0e-4e16-936e-d9a86e45db7b"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp6UZG1okGRvrGqcapOqapBqa6Voam6XqplgmWpilmpimJJknAQCF1hXg"*)(*]VB*)

UI Updateโ€‹

Insert cell before button (was requested via Github issues)

Dataset full supportโ€‹

We have finnaly fixed the most buggy thing we have in WLJS - Dataset. Now it does support nested structures, symbolic keys, Entity, Quantity and etc

ExampleData[{"Dataset","Planets"}]
(*VB[*)(FrontEndRef["c824ccdc-c573-4b47-b58b-87b196ec5df0"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJ1sYmSQnpyTrJpuaG+uaJJmY6yaZWiTpWpgnGVqapSabpqQZAACNEBYN"*)(*]VB*)

Extended MMAViewโ€‹

There was a request for interactive native Mathematica's 3D plot. Well, here you go

With[{p = Plot3D[f[x] y, {x,0,10}, {y,0,10}]},
  MMAView[p]
]

Note, that it is important to pass it using With, since MMAView has HoldFirst attribute

Manipulateโ€‹

Works for 2D, 3D, in general any expression!

Manipulate[Plot3D[Sin[n x] Cos[n y], {x,-1,1}, {y,-1,1}], {n, 1, 5, 1}] // MMAView


Animateโ€‹

The same works for it

Animate[Plot[Sin[x y], {x,0,1}], {y,0,5}] // MMAView

ListAnimateโ€‹

We added the support for raster ListAnimate (not related to MMAView)

ListAnimate[Table[Rasterize[Plot[Table[x^k, {k, 1, n}] // Evaluate, {x,0,10}]], {n,1,6}]]

Easier REST-APIโ€‹

We refined our REST API and added a helper Javascript class of function to make the process easier. Imagine, you can build up a minimal Notebook interface by youself just in a few lines!

.html

<script type="module">
  const stateField = document.getElementById("stateField"), 
        submitButton = document.getElementById("submit_button"),
        codeArea = document.getElementById("code_area"),
        resultsDiv = document.getElementById("resultsDiv");

  async function start() {
    stateField.innerText = 'Connecting to Kernel';

    const kernel = await server.findKernel();
    console.warn('Obtained Kernel', kernel);
    stateField.innerText = 'Ready!';

    submitButton.addEventListener('click', async () => {
      const transaction = await server.createTransaction(kernel, codeArea.value.trim());
      stateField.innerText = 'Evaluation...';

      const results = await server.getResult(kernel, transaction);
      console.warn('Ready');
      stateField.innerText = 'Ready!';

      results.forEach(({ Display = 'codemirror', Data }) => {
        const parentelement = document.createElement('div');
        resultsDiv.appendChild(parentelement);
        new window.SupportedCells[Display].view({ element: parentelement }, Data);
      });
    });
  }

  (async () => {
    await server.waitForConnection();
    start();
  })();
</script>

Yes, apart from header and body parts, that's all you need


MDX/React Integrationโ€‹

This share option lets you embed cells or an entire notebook to MDX-based websites (personal blog or a React App in general).

Here is an online demo of a static website made using Next.js