Changelog
All Holochart packages (@mk7s/holochart and every @mk7s/holochart-*) share one version number and are released together, so one list covers them all. Each entry names the packages it changed.
Under each version, changes are grouped by the size of the bump they ask for:
- Minor changes add something (an attribute, a trace type, an export, an event, an option) or deprecate something. Before 1.0 a minor change may also break existing code; such an entry starts with "BREAKING:".
- Patch changes are bug fixes, performance work, rendering fixes and documentation. They never contain a breaking API change. Rendered pixels may still differ (anti-aliasing, tick placement, text metrics).
The list is generated from the project's changesets: one note per change, written by the author of the change when it is merged.
No version has been published yet. The changes under "Unreleased" ship in the first release.
Unreleased
Merged, but not in a published version yet. The next release is a prerelease, published under the alpha npm dist-tag.
Minor changes
First public alpha of Holochart: declarative, Plotly-compatible charts drawn on the GPU with three.js. Figures are Plotly's
{ data, layout, config, frames }, with the same attribute names, defaults and events. All 14 packages share one version. This is an alpha on thealphanpm dist-tag: APIs may still change in any0.xminor.Install
npm i @mk7s/holochart threegives the full bundle. TypeScript users also add@types/three. The individual packages (-core,-runtime,-traces-*, …) build smaller bundles withregister(...).threeis a peer dependency,>=0.180.0 <0.187.0. The upper bound is the next three.js minor after the newest one tested in CI, and it is widened per release.@types/threeis an optional peer with the same range for the packages whose types expose three's (@mk7s/holochart,-render,-runtime,-components,-traces-3d).- ESM-only. Every export has a
defaultcondition afterimport, so Node 22'srequire(esm)and tools that only knowdefaultcan load the packages. The browsers supported have WebGL 2 and ES2022. Node ≥ 22 runs the renderer-free parts (@mk7s/holochart-core). - Locales are a separate install:
@mk7s/holochart-locales.
Chart types
35 trace types, each with Plotly's attributes, defaults, hover and events:
- Basic:
scatter(markers, lines, splines, steps, text, error bars, areas withfill/stackgroup/groupnorm, bubbles),bar(grouped, stacked, relative, horizontal,base, periods),pieand donuts,table(virtualized rows, wrapped text, draggable column order), and atimeline()helper for Gantt charts. - Statistical (
-traces-stats):histogram(Plotly's auto-binning, everyhistfunc/histnorm, cumulative),histogram2d,histogram2dcontour,box,violin,splom,parcoords(brushing, axis reordering) andparcats, plus astrip()helper. - Scientific (
-traces-sci):heatmap(one GPU texture,zsmooth, annotated cells),contour(everycontours.coloring, constraint contours, labels placed like Plotly's),image, and polar subplots withscatterpolar(radar charts) andbarpolar(wind roses). - Financial (
-traces-finance):ohlcandcandlestick(range slider by default,%{change}in hover),waterfall,funnel,funnelareaandindicator(numbers, deltas, angular and bullet gauges). - Hierarchical and flow (
-traces-hier):sunburst,treemapandiciclewith Plotly's 750 ms drill-down transitions and path bar, andsankey(d3-sankey layout, draggable nodes, loops, and thelink.flowparticle extension). - 3D (
-traces-3d): scene subplots (layout.scene, cameras, turntable / orbit / pan / zoom, touch, 3D hover with spikes,scene.annotations) withscatter3d(1M points in one draw call),surface,mesh3d(Delaunay, convex hull, alpha shapes),cone,streamtube,isosurfaceandvolume(Plotly's stacked isosurfaces or GPU ray marching). Holochart extensions:bar3d, tube and ribbon lines, lit spheres, three.js materials and scene lights,chart.animateCameraandscene.autorotate. - 2.5D (full bundle):
layout.view3dtilts cartesian subplots in perspective.depth,bevelandmaterialextrude bars, funnels, waterfalls, heatmaps, filled areas, pies, treemaps and icicles, and hover, click and zoom stay exact on the tilted plane.
Not yet supported Plotly traces: maps and geo (
scattergeo,choropleth,scattermap,densitymap, …),carpet/scattercarpet/contourcarpet,scatterternary, and the quiver and streamline figure factories.Layout and components
- Axes: linear, log, date and category / multicategory, with Plotly's tick generation and
tickformat. Alsorangebreaks, linked axes (matches),scaleanchoraspect locks, overlaying and shifted axes, spikelines, automargin,layout.gridandmakeSubplots(). - Legends: multiple legends (
legend2, …), group titles, scrolling pastmaxheight, and click / double-click toggling as in Plotly. - Colorbars, annotations (with arrows, rich text, drag and
clicktoshow), shapes (drawing and editing,addHline/addVrecthelpers), layout images,updatemenus,sliders, the range slider and range selector,layout.selections, and the modebar with Plotly's buttons, custom buttons and the 3D group. - Rich text: Plotly's pseudo-HTML (
<b>,<i>,<sup>,<span style>, links, …) in every text attribute. Text is drawn as SDF glyphs on the GPU. - Styling:
marker.patternfills, custom SVG-path marker symbols (symbols.register), emoji and image markers,styleRules(JSON conditions that style points by their data) and per-point style functions.
Runtime API
- Plotly's functional API:
newPlot,react,restyle,relayout,update,addTraces,deleteTraces,moveTraces,extendTraces,prependTraces,purge,addFrames,deleteFrames,animate,toImageanddownloadImage. There is also an object API (createChart(el, figure),getChart(el)) withchart.readyand update promises. - Events: Plotly's events (
hover,click,selected,relayout,restyle,legendclick,sunburstclick,animatingframe, …), also under theirplotly_*names. A listener that throws no longer stops the chart or the other listeners. - Interaction: hover modes (including unified hover), zoom, pan, box and lasso selection (on polar subplots too), scroll zoom, touch with pinch-zoom, and keyboard navigation between data points.
- Animation:
reactwithlayout.transitionandfigure.frameswithanimate. Every Plotly easing is supported, points are matched byids, and Plotly's Play / Pause buttons and frame sliders work. - Big data: streaming with
extendTraces, min/max level of detail for lines of millions of points, and typed-array data. - Export:
toImage/downloadImageto PNG, JPEG or WebP at any size and scale.chartToJSON/fromJSONround-trip figures. - Errors: without WebGL 2,
newPlotrejects withWebGLUnavailableErrorand the container shows a note and the chart's text description. Errors extendHolochartError.
Themes and the default look
- New charts use the dark, dense
holocharttemplate, drawn with the bundled TeX Gyre Heros font. The font is loaded lazily and nothing is fetched from a CDN. Uselayout.template: 'plotly-classic'(orsetDefaultTemplate('plotly-classic')) for Plotly's own look. - 16 built-in themes:
holochart,plotly-classic,high-contrast,high-contrast-dark,neon, and plotly.py'splotly,plotly_white,plotly_dark,ggplot2,seaborn,simple_white,presentation,xgridoff,ygridoff,gridonandnone.holochart-darkis a deprecated alias ofholochart. - Every plotly.py palette and colorscale, plus
colors.register,colorways.register,fonts.registeranddefineTemplate.
Express
@mk7s/holochart-expressbuilds figures from row objects, column objects, Apache Arrow tables or CSV, following Plotly Express (camelCase). The functions arescatter,line,area,bar,timeline,pie,histogram,box,violin,strip,ecdf, the density charts,imshow,scatterMatrix, the parallel charts,funnel, the polar charts,sunburst,treemap,icicle,scatter3dandline3d. They support facets,animationFrame, marginals, trendlines (OLS, LOWESS, rolling, expanding, EWM) andff.distplot.Locales and accessibility
- Locales:
config.localetranslates the UI and formats numbers and dates.@mk7s/holochart-localesships plotly.js's 76 locales as ES modules and<script>files, and plotly.js locale modules register as they are. Arabic and Hebrew text is laid out right to left. - Accessibility: charts are
role="figure"with a generated description, summaries of trends and extremes, and data tables (chart.describe(),config.a11y). There is keyboard access to points, legends, menus, sliders and the modebar. Also a high-contrast theme, the colorblind-safeSafecolorway, automatic patterns (a11y.patterns) and reduced-motion support.
Script-tag builds
@mk7s/holochart/dist/holochart.iife.min.jsdefineswindow.Holochart, with three.js bundled. It is everything but 3D, and the bare jsDelivr / unpkg URL serves it. Types for the global are in@mk7s/holochart/global.holochart-3d.iife.min.jsis a 3D add-on, loaded after the main script of the same version. It adds 3D scenes, 3D traces and 2.5D, and reuses the main script's three.js.- Each locale is a script:
@mk7s/holochart-locales/dist/scripts/holochart-locale-<code>.js.
Known limitations
- WebGL 2 only. There is no Canvas 2D or SVG fallback, and no SVG or PDF export (
toImagegives raster images only). - Tested in Chromium. Visual and interaction tests run in headless Chromium. Firefox and Safari should work but aren't tested in CI.
- Missing features: the Plotly traces listed under Chart types, non-Gregorian calendars, LaTeX, and keyboard navigation for most 3D traces.
- Experimental APIs: the low-level
rendernamespace and the trace and component contracts in@mk7s/holochart-runtimemay change in any minor release.
Packages:
@mk7s/holochart,@mk7s/holochart-components,@mk7s/holochart-core,@mk7s/holochart-express,@mk7s/holochart-locales,@mk7s/holochart-render,@mk7s/holochart-runtime,@mk7s/holochart-themes,@mk7s/holochart-traces-3d,@mk7s/holochart-traces-basic,@mk7s/holochart-traces-finance,@mk7s/holochart-traces-hier,@mk7s/holochart-traces-sci,@mk7s/holochart-traces-stats.Typed figures.
@mk7s/holochartexportsFigure,Data(every trace type, discriminated ontype),Layout,ConfigandFrame, generated from the attribute schemas, andcreateChart,newPlot,react,addTraces,relayout,updateandtoImagecheck figures against them. Each trace package exports its trace types (ScatterTrace, …) and their union (TracesBasic, …); core'sFigureInput<D, L>stays loose by default for partial bundles and plugins, and plugins add trace types toTraceTypes.restylekeeps untyped attribute paths. Published types now also compile underexactOptionalPropertyTypes.Packages:
@mk7s/holochart,@mk7s/holochart-components,@mk7s/holochart-core,@mk7s/holochart-express,@mk7s/holochart-locales,@mk7s/holochart-render,@mk7s/holochart-runtime,@mk7s/holochart-themes,@mk7s/holochart-traces-3d,@mk7s/holochart-traces-basic,@mk7s/holochart-traces-finance,@mk7s/holochart-traces-hier,@mk7s/holochart-traces-sci,@mk7s/holochart-traces-stats.A curated export surface. Nothing changes at runtime; this is about which names are API.
BREAKING:
@mk7s/holochartexports a list of names instead of everything its packages export. It keeps the chart API, typed figures, the trace and component modules, themes, errors, the documented helpers and the experimental plugin API. The plumbing the packages share with each other is gone from it (layoutBars,calcBar,supplyColorscaleDefaults,stashSplomAxis,RANGESELECTOR_Y_PAD,stripInternal,editDistance,warnOnceand about 600 more), and so issetBarExtruder. Those names stay exported from their@mk7s/holochart-*packages, tagged@internal: not API, no compatibility promise. The script-tag globalwindow.Holocharthas the same names as@mk7s/holochart.BREAKING: exports that were stable by default are now tagged.
@internal: what only sibling packages import (in core, components and the trace packages).@experimental: what a plugin is written with, namely core's schema DSL (attr, the schema types and schema objects), color and date parsing and update planning, the trace packages' attribute schemas and calc types, the 3D scene API, and theChartmembersemit,getCalcdata,previewRanges,commitRangesandrefreshHover. TheChartconstructor is@internal; usecreateChart.BREAKING: names that meant different things in different packages were renamed on the less public side.
- core and runtime:
Layoutis nowBaseLayout,FrameisFrameInput; core:LayoutTitleisBaseLayoutTitle. The plain names are the full bundle's types. - traces-basic, traces-finance, traces-hier, traces-sci:
BarTrace,PieTrace,ScatterTrace,FunnelTrace,WaterfallTrace,IcicleTrace,TreemapTraceandHeatmapTraceare nowBaseBarTrace,BasePieTraceand so on. The plain names are the full bundle's types, which add the 2.5D attributes. - traces-basic:
TimelineOptionsisTimelineFigureOptions; traces-stats:StripOptionsisStripFigureOptions; express:AnimationOptionsisAnimationFrameOptions. - Experimental names: core's
TraceModuleandComponentModuleareCoreTraceModuleandCoreComponentModule, itsRGBAandPrimitiveareRGBAColorandPrimitiveValue; the runtime'spointInPolygonispolygonContains; render'sLineOptionsisLinePrimitiveOptions.
Types that leaked into the declarations under bundler-made names have real ones: core's
AttrBuilders(the type ofattr), the runtime'sTraceIndices, and render'sMeshLazy,LinesMarkers3DLazy,ExtrusionLazyandPatternCodenamespaces (type-only).Migration: import the figure types of the full bundle from
@mk7s/holochartas before (BarTrace,Layout,Frameare unchanged there). In a partial bundle, rename the types above. If you imported an@internalname, copy the code you need. See "Unreleased: a curated export list" in the migration guide.Packages:
@mk7s/holochart,@mk7s/holochart-components,@mk7s/holochart-core,@mk7s/holochart-express,@mk7s/holochart-render,@mk7s/holochart-runtime,@mk7s/holochart-traces-3d,@mk7s/holochart-traces-basic,@mk7s/holochart-traces-finance,@mk7s/holochart-traces-hier,@mk7s/holochart-traces-sci,@mk7s/holochart-traces-stats.- core and runtime:
Keyboard navigation reaches every chart family. With the plot area focused, the arrow keys now step through histogram bins, the statistics of each box and violin, heatmap, contour and histogram2d cells (a cell cursor: ← / → along the row, ↑ / ↓ along the column), funnelarea stages, sunburst, treemap and icicle nodes (← / → siblings, ↑ the parent, ↓ the first child; Enter drills and the cursor stays on its node), sankey nodes and links (↓ downstream, ↑ upstream), parcats categories, parcoords lines on each axis, polar points and bars, and scatter3d points. Every stop shows the hover label a pointer would get there and announces what it says, with its place in the chart ("row 2 of 3, column 1 of 4", "level 2, 1 of 5, children: 2").
3D scenes take the view keys: Shift + arrows orbit the camera in 15° steps,
+/-move it in and out and0resets it, each as onerelayoutofscene.camera.bar3d,cone,streamtube,isosurface,volumeandmesh3ddescribe themselves to assistive technology (what is drawn, the box it spans, and a headline value), likescatter3dandsurface.The code for all of this loads on first use, in one small chunk per trace package: the keyboard stops on a chart's first keyboard focus, the 3D descriptions right after a chart with a 3D trace is first described (it shows the generic line until then, and
chart.describe()waits for it). The descriptions ofscatter3dandsurfacemoved into that chunk too. The script-tag build (holochart.iife.min.js) does not include the 2D families' stops yet; its 3D add-on includes the 3D chunk.Announcements read the lines of a hover label as a list, so a pie slice is now "Share: Alpha, 40, 40%, point 1 of 5." instead of "Share: Alpha 40 40%, point 1 of 5."
For trace module authors:
keyboardPointsmay return stops that say where the arrows lead (KeyboardPoint.nav), show several labels (more) and bring their own announcement (say), or a list that builds its stops on demand (KeyboardStops); cartesian modules may have stops too.TraceModule.a11yloads a module'skeyboardPoints,describeandkeyboardView(view keys of a trace that is not on cartesian axes) from a chunk of its own.sceneA11ygives a trace built on the 3D scene its view keys, andHoverContext.heightis the figure height for domain traces.Packages:
@mk7s/holochart,@mk7s/holochart-runtime,@mk7s/holochart-traces-3d,@mk7s/holochart-traces-finance,@mk7s/holochart-traces-hier,@mk7s/holochart-traces-sci,@mk7s/holochart-traces-stats.Maps. The new package
@mk7s/holochart-traces-geohas thegeosubplot (layout.geo,geo2, …) and thescattergeoandchoroplethtraces: Plotly's projections, scopes,fitbounds, graticule and base layers (land, ocean, coastlines, countries, lakes, rivers, subunits) atresolution110 or 50; pan, zoom and rotate with Plotly's relayout keys; markers, great-circle lines, text andfill: 'toself'atlon/lator atlocations; and regions colored by value, from the basemap (locationmode'ISO-3','USA-states','country names') or from your owngeojsonwithfeatureidkey. Express gainshx.scatterGeo,hx.lineGeoandhx.choropleth.A 3D globe, which Plotly does not have:
projection.type: 'globe3d'is the orthographic view drawn as a lit sphere, with the same rotation, scale, gestures and relayout keys. It turns by a matrix, so a rotation projects nothing at any resolution. On itscattergeolines are arcs lifted above the surface (line.lift), and a choropleth's regions can rise as prisms by a second value (elevation,elevationscale), picked on the GPU so that nothing behind the globe or behind a prism is hit. These three attributes are Holochart's own and are ignored on a flat map. The globe's code is a lazy chunk, loaded when a figure has one.The full bundle does not include it, so an app without a map downloads no map code. Add it with one import;
@mk7s/holochartdepends on the package, so there is nothing more to install:tsimport * as Holochart from '@mk7s/holochart'; import '@mk7s/holochart/geo';@mk7s/holochart/georegisters the package and re-exports it. A partial bundle registers it like any trace package:register(...tracesGeo). Ascattergeoorchoroplethtrace, orlayout.geo, on a chart without the package is ignored, and the warning now names the package and that import. The script-tag build has no maps yet.The basemap is Natural Earth 5.1.2 (public domain), built into the package as lazy chunks, two per resolution (about 40 kB gzipped for 1:110m, 285 kB for 1:50m), loaded when a map first needs them: a map makes no request outside the app's own bundle and works offline. Disputed boundaries are drawn by de facto control. The 15 projections of d3-geo are in the package's own code, and the country-name table of
'country names'is a lazy chunk of its own; Plotly's other projection types load d3-geo-projection in one lazy chunk the first time a figure names one.New
config.topojsonURL(core), with Plotly's meaning: when set, basemap files are fetched from<url>/world_110m.jsonand so on instead of the bundled data. Unlike Plotly it defaults to empty, which fetches nothing. Theholocharttemplate has ageoblock, so maps match the dark look (land a step above the background, lakes cut out of it).For subplot authors (runtime, experimental):
SubplotViewportOptions.kind: '2d'gives a non-cartesian subplot a pixel-space viewport like a cartesian subplot's instead of a 3D camera;DomainLayoutContext.chartis the chart, for subplots that keep state from one layout pass to the next; and a component view withclickThroughlets a press it took for dragging become a click on the point under it. A hover label now goes away when a component drag starts, and no longer appears under a finger lifted after a touch pan.Render (experimental):
MeshData.depthTestanddepthWrite, for a mesh that lies on a surface already drawn;loadPicker()andloadFillTriangulation(), which give lazy code the pickers and the polygon triangulation without bringing them into an app's initial chunk.Packages:
@mk7s/holochart,@mk7s/holochart-core,@mk7s/holochart-express,@mk7s/holochart-render,@mk7s/holochart-runtime,@mk7s/holochart-traces-geo.More network graphs: two more trace types in
@mk7s/holochart-traces-graph, interaction, accessibility and large graphs.chord: a chord diagram, which Plotly does not have. Flows between nodes as ribbons inside a ring, from thenode/linkcontainers ofgraphandsankeyor from a squarematrixwithlabels.directedribbons can end in an arrowhead (link.arrowlen),node.groupadds an outer ring of groups, ribbons are colored by their source, their target or a gradient (link.colorsource), and a hover keeps the ribbons of one node. It is placed bydomain.graph3d: thegraphmodel in a 3Dscene: a force layout in three dimensions,'layered'with one plane per rank, or'preset'positions on the scene's axes. Nodes are lit spheres or sprites, links lines or tubes with cone arrowheads, parallel links fan out and a self-link is a ring. Nodes and links are picked on the GPU. Register it withtracesGraph3d, which brings the scene;tracesGraphalone bundles no 3D code.import '@mk7s/holochart/graph'registers both.- Interaction (
graph): a hover highlights a node's neighbourhood (highlight.hops,direction,dim,color,nodes), and two selected nodes highlight a shortest path between them (highlight.path,pathweight,pathdirected;graphPath(trace)returns it). Nodes can be dragged under'preset'and'force'(node.draggable): the release restylesnode.x/node.y, which pins a node of a force layout, and a double-click releases it; withforce.simulatethe layout reacts while a node is dragged.force.startcontinues a layout from given positions. Selection points list the links among the selected nodes, and%{neighbors}is a hover template variable. - Large graphs (
graph):worker: 'auto' | true(orconfig.worker) runs the layout in the package's layout worker,dist/layout-worker.js, and draws the nodes while they settle; where a worker cannot start, the same code runs on the main thread in slices.lodleaves labels, arrowheads and node outlines out of a large graph until a zoom makes them readable, and fades links by how densely they cover the plot.link.bundlebundles links ('hierarchical'through the nodes' groups,'force'for graphs without groups). Exported for apps that lay graphs out themselves:layoutInWorker,setGraphWorkerUrl,bundleLinks. - Accessibility: the description of a graph names its most-connected nodes, its connected components and its groups, and its data table is the list of links. Arrow keys move from a node along its links (siblings, parent and child in a tree; rank by rank in a layered graph), and Enter folds a tree node. Five new announcement sentences and
Folded.are translated in the ten locales.
For trace authors (experimental):
TracePlotContext.recalc()asks for a second calc pass without a change of the figure (a layout that arrived);HoverPoint.selectsnames the points a click on this one selects;eventDatagets the selection as a fourth argument;KeyboardPoint.clicklets Enter reach the click handling of a cartesian trace that handles clicks itself;KeyboardStops.locatere-finds the cursor in stops built on demand.TraceAxisHintsgainsz, and a 3D scene whose traces all hide their axes hides its own and starts with a closer camera.Packages:
@mk7s/holochart,@mk7s/holochart-core,@mk7s/holochart-locales,@mk7s/holochart-runtime,@mk7s/holochart-traces-3d,@mk7s/holochart-traces-graph.A chart created in a hidden or unsized element (an inactive tab, a closed dialog) no longer stays at 700 × 450: without
config.responsiveit now takes the element's size once, the first time the element has one.New
config.maxPixelRatio(default 2): the upper limit of the pixel ratio thatpixelRatio: 'auto'takes from the display.Polar zoom-box drags work for charts in another window's document (an iframe or popup created by the page's script).
An unknown trace type that is one of Holochart's own now says which package to register: "
sankeyis in @mk7s/holochart-traces-hier; import it from there and callregister(sankey)". Core exportstracePackage, and the warn-once helperswarnOnceanddeprecate. The new "Errors and warnings" reference page lists which calls reject and which warn.Packages:
@mk7s/holochart-components,@mk7s/holochart-core,@mk7s/holochart-render,@mk7s/holochart-runtime,@mk7s/holochart-traces-sci.Dashboards no longer run out of WebGL contexts. Browsers keep about 16 per page (8 on mobile) and blank the oldest canvas beyond that; a page of Holochart charts now uses at most 6 however many charts it has. The first 4 charts get a context of their own and later ones draw through one shared renderer, which renders each chart and copies the frame into that chart's canvas.
toImageanddownloadImagealways draw through the shared renderer, so exporting no longer takes a context per call.New
config.sharedRenderer:'auto'(default),trueto always share,falseto always take a context. On a shared chartchart.three.renderer.domElementis not the chart's canvas: usechart.three.root.canvas. See the Dashboards guide and ADR-023.Packages:
@mk7s/holochart-core,@mk7s/holochart-render,@mk7s/holochart-runtime,@mk7s/holochart-traces-3d,@mk7s/holochart-traces-hier.Network graphs. The new package
@mk7s/holochart-traces-graphhas thegraphtrace, which Plotly does not have: nodes (node.label,x,y,size,color,symbol,group) and the links between them (link.source,target,value,color,width,dash,arrow), shaped like sankey's so the same data feeds both, or theids/labels/parentsof the hierarchical traces. Links can have arrowheads, which stop at the edge of their node, parallel links curve apart and a self-link is a loop. Nodes are markers, sized bynode.sizeor by their number of links (node.sizeby), or boxes around their labels (node.shape: 'box'). Labels are culled where they collide: the most connected nodes keep theirs and the rest appear on zoom. Nodes are colored by group, with one legend item per group, or by value, with a colorbar. Hover works on nodes and links, and box and lasso selection on nodes.arrangementsays where the nodes go.'preset'takesnode.xandnode.yas data on the trace's axes, so a network can sit over a scatter, on date or log axes. Every other value computes the positions, with a deterministic layout that is also exported as a pure function over typed arrays, and each has an option container of its name:'force'(the default without positions;force): a force-directed layout, as springs and repulsion (force.algorithm: 'spring') or ForceAtlas2. Nodes with anxand ayare pinned; when every node has anxand none ay, the x axis stays a real axis and the layout only moves the nodes along y (a timeline).force.simulate: trueshows the layout settling and ends on the same picture; it is skipped underprefers-reduced-motionand for graphs of more than 2,000 nodes or 10,000 links.'layered'(layered): a directed graph in layers (rankdir,ranksep,nodesep,ranker), with links routed as splines, polylines or right angles (routing). Labelled nodes are boxes and links have arrowheads by default;layered.clustersframes the nodes of each group under its name; the links of a cyclic graph that had to be turned around are drawn in thelink.secondarystyle (dashed).'tree','radial','dendrogram'(tree): a tidy tree, the same tree on rings, and a tree with its leaves on one line and its nodes at the heightsnode.valuegives, on a visible axis. They takeids/labels/parentsornode/link; links that are not part of the tree are drawn in thelink.secondarystyle. A click on a node that has children folds or unfolds its subtree: the chart restylestree.collapsedand the tree moves to its new shape.'arc'(arc) and'hive'(hive): an arc diagram and a hive plot.'circular'and'grid', and'custom', which runs a layout the app registered withregisterGraphLayout(name, layout).
New with them:
node.value(a number per node: a dendrogram's heights,tree.sort,hive.position,%{value}in hover labels) andlink.secondary(dash,opacity,color). Labels have room where the arrangement leaves some (node.textposition: 'auto'): along the radius of a radial tree, upright under an arc diagram or the leaves of a dendrogram. Box nodes of a computed arrangement shrink with the axes, text included, when the diagram is larger than the plot area.The trace is cartesian: it draws on its
xaxisandyaxis, so zoom, pan, selection,uirevision, subplots and image export work as for a scatter. With a computed arrangement the axes are hidden, unless another trace shows them or the figure setsvisible, and locked to one scale (a tidy tree and a dendrogram fill the plot area along each axis instead).The full bundle does not include it, so an app without a graph downloads no graph code. Add it with one import;
@mk7s/holochartdepends on the package, so there is nothing more to install:tsimport * as Holochart from '@mk7s/holochart'; import '@mk7s/holochart/graph';@mk7s/holochart/graphregisters the package and re-exports it. A partial bundle registers it like any trace package:register(...tracesGraph). Agraphtrace on a chart without the package is hidden, and the error names the package and that import. The script-tag build has no graphs yet.For trace authors (core, experimental): a trace module can give
axisHints(trace), which returns aTraceAxisHints:hide(the axes, or with'x'/'y'that axis, default tovisible: falseunless another trace is on them),equal(the y axis defaults toscaleanchoron the trace's x axis),reverse('x'or'y': that axis defaults toautorange: 'reversed'), andx/y(the data the trace puts on its axes when that is not itsx/yattribute, for axis type detection).Packages:
@mk7s/holochart,@mk7s/holochart-core,@mk7s/holochart-traces-graph.Accessibility strings in ten locales.
de,es,fr,it,ja,ko,pt-BR,ru,trandzh-CNnow translate Holochart's own strings, which plotly.js's locales don't have: the generated chart summaries (until nowde,esandfronly), every keyboard announcement ("Revenue: (Mar 1, 2024, 11), point 3 of 6.", "Zoomed in.", "View rotated.", the row, level and category sentences of grids, hierarchies and parcats), the name of the legend's keyboard toolbar and the plot area's keyboard hint. Regional locales that fall back to one of them (de-CH,es-AR,es-PE,fr-CH) get its strings; every other locale falls back to English, sentence by sentence (pt-PT,zh-TWandzh-HKfall back topt-BRandzh-CNfirst when those are registered too, as they already did for Plotly's UI strings).The same ten locales also fill gaps among the UI strings a chart looks up: the titles of the modebar's drawing buttons ("Draw line", "Erase active shape", …), and in
koandpt-BRthe hover labels of box, violin, OHLC and candlestick (open:,median:, …), which plotly.js has under keys without the colon, plus the default trace name inko.These are machine translations that no native speaker has reviewed; the locales guide and the accessibility guide say so, and say what is still English: the rest of the hidden description (chart type sentence, axis and trace lines, table captions) and a few control names ("Chart toolbar", "Menu 1", "Slider 1", "Range selector"). To correct a sentence, register the locale with your own entry for its English key.
A parcoords dimension without a label is now named through the locale dictionary in its keyboard stops (
'Dimension {n}'), instead of always in English.The ten locale modules grow by 1 to 2.5 kB each (gzipped), to 3 to 4 kB; nothing is added to the core bundles. The locales guide now also states the limits of right-to-left text: legends, menus and axes are not mirrored, and measuring text without a browser has no bidi or shaping.
Packages:
@mk7s/holochart-locales,@mk7s/holochart-traces-stats.BREAKING:
chart.toJSON()is removed. CallchartToJSON(chart)instead; it returns the same figure and reads the chart's registry through the newchart.registry. The method made every bundle carry the serializer (about 2.3 kB), also in apps that never save a figure.JSON.stringify(chart)now throws aTypeErrorthat nameschartToJSON.Migration: replace
chart.toJSON()withchartToJSON(chart), andJSON.stringify(chart)withJSON.stringify(chartToJSON(chart)).Packages:
@mk7s/holochart,@mk7s/holochart-runtime.Charts come back complete after the browser takes the WebGL context away and restores it (a GPU reset, a long time in a background tab). Buffers, textures, text and picking already did; a 3D scene's generated environment (
lighting.environment: 'studio' | 'city') did not, which left metallic and physical materials black. It is now drawn again onwebglcontextrestored.Texture sizes follow the device instead of an assumed 4096:
chart.three.root.capabilitieshas the context'smaxTextureSizeandmax3DTextureSize. Heatmaps pack their values into rows that fit, and a heatmap, image, surface or volume grid too large for the GPU logs a warning and is not drawn, instead of drawing black.Packages:
@mk7s/holochart-render,@mk7s/holochart-traces-3d.Express gains three network functions (experimental), which plotly.express does not have:
hx.graph,hx.chordandhx.adjacencyMatrix. They read an edge table, one row per link with the ids of its two ends (source,target,weight), and an optional node table (nodes, matched byid) for labels, colors, sizes, symbols, positions and hover text.colorgroups the nodes, with one color and legend item per value, or maps a numeric column through a colorscale;sizetakes a column or'degree';directeddraws arrowheads;arrangementpicks the layout of agraph, with its options under the trace's own names (force,layered,tree,arc,hive).hx.chordalso takes a square matrix.hx.adjacencyMatrixdraws the network as a heatmap with rows and columns sorted byorder('input','degree','group','community'or a list of node indices), so that clusters show as blocks on the diagonal.The functions only build figures, so Express still depends on no trace package. Drawing a
graphor achordneeds the graph package registered:import '@mk7s/holochart/graph'.@mk7s/holochart-traces-graphnow exports its data helpers: the adaptersfromEdgeList,fromAdjacencyMatrix,fromNodeLink(networkx, d3, graphology and Cytoscape JSON) andfromDot(a Graphviz subset), which return thenodeandlinkcontainers of a trace, and the measuresdegrees,connectedComponents,louvain,modularityandadjacencyMatrix. The Express functions take an adapter's result in place of the edge table, and a measure as a node column:hx.adjacencyMatrix(network, { color: louvain(network), order: 'community' }).Packages:
@mk7s/holochart-express,@mk7s/holochart-traces-graph.
Patch changes
Stability tags. The plugin API is now marked
@experimentalin the published types, so editors show which exports may still change in a minor release: therendernamespace (@mk7s/holochart-render, except thefontsandsymbolsregistries), the trace and component contracts and the helpers for module authors in@mk7s/holochart-runtimeand@mk7s/holochart-core, and the chart members typed by those (chart.three.root,.overlay,.viewports,.subplot(),chart.axes,chart.subplots,chart.interaction). Everything else a package exports is stable. Nothing changes at runtime. See the versioning section of the migration guide.Packages:
@mk7s/holochart,@mk7s/holochart-core,@mk7s/holochart-render,@mk7s/holochart-runtime.Large heatmaps draw sooner and lines cost less GPU time, with the same pixels.
A 4096 × 4096 heatmap's first draw takes about half as long. Its values go to the GPU as one float per cell (
R32F, 67 MB) instead of a value and a validity flag (RG32F, 134 MB), calc reads the rows once instead of twice, and the accessible description no longer scans all 16.7 million cells after every pipeline run.packHeatmapValuesnow returns one float per texel, with cells without a value stored as the largest float32.On a 1M-segment pan, a solid line costs 2.1 to 2.6 times three's
Line2instead of 3 to 4 times, and a dashed one 2.4 to 3 times instead of 8. A line with one color keeps it in a uniform instead of a per-vertex buffer (28 bytes per vertex instead of 44), a dashed line no longer recomputes and re-uploads its dash phase while panning, and each segment's quad ends where the pixels it draws end. New in@mk7s/holochart-render:quadReach,QUAD_FRINGEandQUAD_SLACK(the CPU mirror of the quad's extent).Packages:
@mk7s/holochart-render,@mk7s/holochart-traces-sci.3D scenes no longer leave two GPU buffers behind each time their axes are rebuilt at a different size. On the shared renderer those buffers outlived the chart.
Packages:
@mk7s/holochart-traces-3d.Charts created at the same time no longer show text with letters missing. The text engine keeps one glyph atlas for the page and reports a label as typeset as soon as its glyphs are registered; when another chart had asked for the same new glyphs a moment earlier, that was before they were in the texture, and the chart kept the gaps until something else redrew it ("Hourly precipitation (in)" read "ourl pre ipitation in"). Text primitives now watch the atlas together: when typesetting or
preloadTextFontadds glyphs, every chart with text draws one more frame.Packages:
@mk7s/holochart-render.Docs: a chemistry and physics basics demo page that walks through the periodic table, what things are made of, atoms and molecules, motion, waves, fields and the planets with more than 50 charts across 33 trace types, from heatmap, sunburst, parcats and bar3d to isosurface, volume, cone, streamtube, image and an animated pendulum.
Packages:
@mk7s/holochart.Docs: a Dallas weather demo page that charts 87 years of daily readings from Dallas Love Field (NOAA): every daily high and low on one zoomable date axis, the year in days against its records, calendar and month-by-year heatmaps, rain through the year, a wind rose, a 3D temperature landscape, a climate spiral and an animated seasonal curve.
Packages:
@mk7s/holochart.Docs: a TQQQ and SOXL demo page that charts 16 years of the two 3× ETFs, their holdings and how daily leverage behaves, with candlestick, OHLC, indicator, heatmap, 3D bar, surface, contour, sankey, sunburst, treemap, icicle, parcoords, parcats, splom, violin and more.
Packages:
@mk7s/holochart.Hover:
%{text}in ahovertemplate, and the text line ofhoverinfo, now readtextwhenhovertextis empty, its default, as in Plotly (hovertext || text). Before,%{text}came out empty for most trace types (scatter, bar, bar3d, …), and a template of only%{text}showed no label.Packages:
@mk7s/holochart-runtime.