Skip to content

Chart Guru 3D Changelog

All notable changes to the Chart Guru 3D module included with Chart Guru will be documented in this file.

The format follows Keep a Changelog and the project adheres to Semantic Versioning.

  • Setting Lift between 0 and 1 raises pies, donuts, radar plates and surfaces as they turn, so they stay on the plot’s floor instead of swinging below it partway; the flat and lifted drawings are unchanged.

  • Chart3DCameraRig.EnsureRig(host) makes the rig the host’s own when the host has none, so the rig alone shows the pose instead of the content also turning by it.

  • The Charts in a Game World sample stands its back row of bed charts higher, so the front charts’ titles no longer run into the back charts’ month labels.

  • Declare the pose inspector’s immutable metadata lifetime for Unity 6.7 static lifecycle analysis.

  • Pie, Donut and Radar 3D fill their host footprint under data proportions, and date axes keep the full plot instead of collapsing beside value axes.

  • Captures, Canvas and UI outputs, the camera rig and scene legends and titles frame pies, donuts and radars around what they draw instead of their empty plot box, so a round chart no longer sits in the bottom of the image.

  • Rules up to the default width draw as unlit lines in their series color, like the axis lines, instead of pixel-wide lit tubes that showed some rules nearly black; wider rules stay shaded tubes.

  • Rule, Rectangle and Surface 3D draw every value column, on depth lanes when no Z is bound; Stacked Area 3D stacks its series; bars and candles on date axes span their share of the date spacing; Radar 3D places corners on their category spokes.

  • Layers that cannot draw report why in the chart’s compile diagnostics and the inspector, and invalid surface functions warn once.

  • A Chart 3D added at runtime starts as Bar 3D, and MorphTo between 3D types animates through the 3D compiler’s own type transition, without claiming a 2D morph recipe.

  • Streaming Bar 3D updates reuse their flattened layout and scales instead of rebuilding them, and the value-update plan lives in the host’s update cache.

  • 3D legends match 2D (gradients, symbol shapes, missing heat cells), and 3D ticks honor Use Nice Ticks, per-tick labels, formatters, log ticks below 1 (0.01 instead of 0, tiny decades included) and the Truncate label policy.

  • Chart 3D Image, Texture and Element share one Canvas output core and the same view shortcuts (Theme, Appearance, Pose, Projection, AutoRotate, Zoom, Lift, PlayLift, ClearSelection); the element adds ChartType, MorphTo and ResetViewport and works with the UI Toolkit Chart Binder; the outputs’ Chart setters are removed in favor of SetChart.

  • One surface material setting: the chart’s Style > Material preset (Chart3DSurfacePreset), with the host’s Material Override winning; the host Surface Preset and Chart3DMaterialPresets.Kind are removed.

  • The camera rig auto-frames like outputs, writes its camera only on change, documents its units and keeps Min Distance below Max; Apply Scene Environment no longer saves the chart’s lighting into the scene; render failures log once with their owner; Anti-Aliasing is a sample-count choice and Supersample a 1 to 4 range.

  • Inspectors: 3D outputs get Look, View Pose and View Projection rows, Export PNG and Diagnostics; Orbit moved to Behavior; pose presets; settings that do not apply are hidden; 3D chart assets preview in 3D.

  • Create menus read GameObject/Chart Guru/3D/Bar Chart, Point Chart and Surface Chart and GameObject/UI/Chart Guru/3D Bar Chart, with a 3D UXML template.

  • Removed the unused Built-in surface shader and the unused render-pipeline version defines.

  • Fix Unity 6.7 lifecycle generation for the 3D domain publication cache by declaring its cleanup owner partial and explicitly initializing its cached state.

  • Create world-space charts with a front pose in the cloned scene definition so rendered geometry follows the GameObject transform, while retaining the Designer document’s camera pose and runtime orbit behavior.

  • Render scene chart titles and subtitles with the shared title model, camera-facing placement outside axes and legends, framing bounds and pooled label cleanup; suppress scene presentation in UI outputs that already draw their own title blocks.

  • Resolve the chart’s selected surface material in mesh and point-instance rendering independently of per-layer roughness and metalness overrides, including Designer previews and generated C#.

  • Remove Automatic from the Designer projection controls, reframe when switching to perspective, reset preview zoom on projection changes, and restore automatic camera distance when framing. Keep the manual distance slider from clamping the automatic-framing sentinel when the camera drawer binds. Extend output lens zoom down to 0.1 while preserving the authored pose and avoiding geometry rebuilds.

  • Animate both Designer dimension switches with eased camera and depth motion, independently of data-animation settings. Prime the flat output before lifting, consume pending definition rebuilds, and reset the animation clock after setup. Preserve authored camera distance throughout lift transitions.

  • Retain declared and absent local-keyword handles with owned transparent material variants, refresh them when a source shader or keyword space changes, and release them with pruned variants. Draws still copy live source properties without repeating allocating keyword-name lookups; added mixed-shader zero-allocation and shader-change regressions.

  • Move blended submesh boundaries before expanding opaque ranges during highlights and transitions, avoiding transient overlap warnings and their managed logging allocations while retaining complete index validation and bounds. Added warning, opacity-partition and growing/shrinking transition topology regressions.

  • Widen transition mesh indices before restoring opaque and blended submeshes, preserving both partitions when entry or data animations start from UInt16 geometry. Added topology, material and highlight-partition regression coverage.

  • The 3D Gallery behaves like the 2D Gallery: double-click and Enter open a copy in the Chart Designer, Rotate on Hover is on by default, and a toolbar button opens the 2D Gallery with the same search. Removed Chart3DGalleryPreviewWindow and the session’s per-view cache keys. Chart3DEditorAddOn supplies the Welcome window’s 3D card with the 3D Gallery, 3D Showcase and 3D Manual, and the 3D Gallery link.

  • Included the full 3D module in the combined Chart Guru release workflow at Reuse/ChartGuru.3D, preserving its manifest, assemblies, GUIDs, examples, manual and AI skills. Retired the independent ChartGuru3D.asset job while keeping module validation gates and the one-way core dependency.

  • Added six AI skills in AI/Skills with an AI/README.md: setup with the scene host, Canvas and UI Toolkit outputs and captures; Swift Charts 3D import and export; surfaces and colormaps; poses, orbit, selection and the lift from 2D; live data updated in place; and 3D themes, labels and legends. Their C# examples compile against the public API.

  • 3D point sizes are diameters, as in 2D charts: PointMark3D.SymbolSize is a sphere’s or billboard’s diameter, a cube’s edge and a cylinder’s or cone’s height in plot units, and layer symbol sizes, literal Size cells and the symbol size range are diameters in points. Spheres and billboards drew at twice those sizes, so 3D points were twice the 2D diameter; hit testing and data label offsets follow the drawn size. Swift Charts 3D sizes a sphere by its radius, so imports double a sphere’s symbolSize and exports halve it, and unsized points draw at Chart3D’s default of 0.03 of the plot, now also PointMark3D’s (0.05 drawn before).

  • Charts keyed by two or more style keys or series draw a legend, as Swift Charts does for foregroundStyle(by:): a scene host shows camera-facing labels after round swatches in the marks’ colors on the side LegendPosition names, aligned by LegendAlignment, beyond its tick labels and axis titles on each camera’s screen and sized like its other 3D text; Chart3DImage and Chart3DElement draw it as 2D legend content in a band their view keeps clear (Chart3DOutputView.ReserveBands takes leading and trailing bands too), and Chart3DTexture and captures show it in the render. Hidden hides it; numeric style keys and gradient color scales draw no key yet.

  • 3D points sized by a Size column span the definition’s symbol size range (ChartScaleSettings.SymbolSizeRange) when it overrides the automatic half-to-twice scale, in compiles and in-place updates.

  • Definition charts update in place when data keeps its shape: source value changes and SetData(frame, shapeChanged: false) write surface heights, point, bar, line and area positions, point sizes, and rule and rectangle extents into the compiled marks without compiling again or allocating once warm; frames that add, remove or regroup marks, and pies, donuts, radars, candlesticks, heat maps and date values, compile as before. Hosts then build once, keeping the mesh and the text of unchanged ticks, and builds reuse the color engine. Chart3DElement, Chart3DImage and Chart3DTexture take SetData(frame, shapeChanged).

  • Data-grid surfaces color height-based against the layer’s Height Range (SurfaceGrid3DMark.YRange), otherwise the chart’s explicit Y domain, so streamed heights keep their colors; they normalized to each frame’s own heights.

  • 3D text scales with the plot: tick labels, axis titles, data labels, slice and radar labels and their gaps take the theme’s LabelScale and LabelOffset times the plot’s largest side, so they keep their share of the plot at every PlotSize. The defaults are calibrated on a one-unit plot to Swift Charts 3D, where a tick label’s cap height is about 3.4% of the plot; text was a fixed world size per font point, so labels filled about a tenth of a 0.45 m tabletop plot and half the native share on the 2 m plots that new scene charts get.

  • Radar plates and ring values map the Y domain like the 2D radar, from its minimum at the center to its maximum on the outer ring, so an explicit 50 to 100 domain draws 75 halfway out where the middle ring reads 75; plates were drawn from zero.

  • Surfaces drawn from a table or a heat map keep drawing when values are missing, as Swift Charts draws no cell for them: a row without a value and a grid position without a row become holes that draw no cell while the rows cover at least half of the grid, and a repeated position keeps its first row. A missing value shortened the sample list below the grid, which dropped the whole surface, so a heat map shown in 3D vanished over one unrecorded hour.

  • Chart3DImage and Chart3DTexture that host their own chart use a Manual Chart Data Source on their GameObject while no Data Source is assigned, like Chart3DComponent and the 2D chart hosts, and follow it when it is added, disabled or removed.

  • The Camera and Output sections of 3D chart and output inspectors keep their expanded state for the editor session when the inspector rebuilds, and Keep Proportions and Orthographic Size replace the Preserve Data Proportions and Manual Orthographic Size labels, which a 400 px inspector cut off.

  • Transitions play from the drawn geometry without building per tick: a data change, an entry animation or a lift builds its target once, paired marks move (instances and meshes alike), new marks grow from their base and removed marks shrink away. While a transition runs the surface mesh carries each vertex’s source position for motion vectors, and instances draw with their previous matrices. Removed Chart3DMorpher, Chart3DMorphRecipes, Chart3DMeshContext.Morpher and TryResolveAnimatedY; builds always use the target values.

  • Added Chart3DComponent.Lift, IsLifting and PlayLift (with Lift and PlayLift on Chart3DElement): a chart flattens into its 2D drawing facing the viewer and lifts back into 3D with its pose. Definitions of every 2D chart type draw flat in 3D hosts, including sparklines, compact pies and donuts, indicators, heat maps as a surface over their cells, and candlesticks as a wick rule and a body rectangle per row. The 2D-to-3D Morph sample lifts one stacked definition.

  • Framing and the instance list skip non-finite geometry, and the builder moves non-finite vertices to the plot center, so one invalid mark can no longer turn the camera NaN and blank a render.

  • Output views frame their first render around labels they just created: text measured before its first layout no longer throws the camera hundreds of millions of units away and blanks the render.

  • 3D axes match native Chart3D: logarithmic scales tick at every power of their base (LogScaleHelper.GenerateDecadeTicks), date scales on calendar boundaries (definition date axes become time axes from their earliest date), explicit AxisMarks(values:) draw nothing at the domain ends, and axis titles follow LabelPosition, lining up with the axis end for Leading and Trailing, and LabelSpacing.

  • Added Chart3DBuilder.ChartForegroundStyleScale(Dictionary<string, Color>), so 3D charts built in code map style keys to colors.

  • Lines draw as round tubes with rounded ends instead of flat ribbons that turned edge-on, and lines and areas curve with InterpolationMethod(...) like 2D charts (Catmull-Rom, cardinal, monotone, natural and steps); layer interpolation, LineMark.Z and AreaMark.Z carry the curve into 3D. Line gradients run across the plot and area gradients across their series’ height, as in 2D.

  • Radar charts draw each series as a translucent plate with an outline and corner points on its own height, over rings and spokes in the grid color with category and ring labels, and start at the top running clockwise; Radar3DMark gained RingStyle, FillOpacity and ShowPoints.

  • Pie and donut slices start at the top and run clockwise around the plot center like 2D pies, Sector3DMark.Explode moves a slice out, data labels follow the chart’s Pie Label Mode on the slice or outside with leader lines, and slices of a gradient take one color each along it.

  • Candle bodies compiled from definitions are 0.6 of the candle spacing wide, so date candles no longer shrink to slivers; added CandleStickMark.Z(z, slot) and Chart3DBuilder.AddHistogramBars, whose bars span their bins.

  • Pie and donut slices fit their plot as 2D pies do: Sector3DMark.OuterRadius, Height and Explode are shares of the plot’s polar radius, half the shorter side of its footprint (defaults 0.9 and 0.24), InnerRadius is a share of the outer radius, Donut3DMark defaults to half, and the slab rests on the plot’s floor, so a lifted pie stands on its contact shadow however tall the plot is. Radar plates stack up from the floor over rings and spokes lying on it. A definition pie in a small plot was almost twice as wide as the plot, and a donut’s 0.5 hole left no ring. Radar plates take the same radius, and both shrink to the plot’s height as a chart flattens. Pies, donuts and radars draw no Cartesian box, axes or grid, and their tooltips point at the middle of a slice’s rim and at a radar corner.

  • 3D charts keep the X, Y and Z domains of their 3D marks after a data, style or layout change. The base chart recompiled stale state with the 2D layout, which knows a surface only by its first sample, so definition surfaces drew as flat clamped planes between walls and charts mixing points and planes stretched X to zero; compiles now publish their domains, builds, chrome and data-proportional plots resolve them again first, and the base chart resolves stale domains of 3D charts with the 3D rules, so EffectiveXDomain read right after a change is right as well.

  • Rows with an empty cell in a channel their 3D mark needs draw nothing and leave the domains alone, as in 2D charts: an empty Z cell no longer puts a point, bar, candle or surface row at depth 0, and empty X End, Y Start, Y End, Z Start or Z End cells no longer fall back to the row’s position.

  • The Multi-Series Metrics and Forecast Ribbons gallery templates and the Showcase draw their lines as thin tubes.

  • Data proportions compare only quantitative axes. Category axes (compiled categories, depth lanes and bar bands) keep one unit per category among themselves, and each group’s longest axis fills the plot box, so six monthly bars up to 80 no longer squeeze into a column 6/80 of the plot wide in scene hosts, the Designer and after Convert to 3D. A single depth lane shows no numeric Z ticks.

  • A numeric Color channel colors 3D marks along the chart’s continuous color scale, the definition’s color scale preset and color domain or a domain over the values, as 2D charts do, and the legend model shows that scale; every number used to become a category with its own palette color. Added Chart3DBuilder.ChartForegroundStyleScale(ColorScale) and ColorScalePresetIndex, which the C# export writes.

  • Chart3DImage and Chart3DTexture in Source mode draw the mirrored chart in its host’s plot size and data proportions instead of their own view options’ ones. A terrain in kilometers across and meters up collapsed to a sliver in a mirror that preserved data proportions its host does not.

  • X and Z tick labels and axis titles rest on the floor plane beyond the plot’s front and side edges, as Swift Charts 3D lines them up, instead of hanging below the floor, so a chart can stand on a surface. They lie flat seen from above and lean toward lower cameras only as far as keeps them below the plot on screen; cameras level with the floor still see them hang below it. The Y title runs up its edge like a 2D Y title, Y tick labels give way to floor labels where the two meet, and an axis seen end-on, such as Y from the top, hides its labels.

  • Radar rings take 0.9 of the plot’s polar radius, the share pie and donut slices reach, so round charts on equal plots read the same size, and each camera places category, corner and ring value labels just clear of their ring, corner or spoke. Ring values that would overlap on screen thin out, and the outer one gives way to the top category.

  • The contact shadow plane is a shadow catcher: clear where nothing shades it and darkening to the theme’s shadow plane color under the marks’ shadows on URP and Built-in, and hidden on HDRP. It drew an opaque slab in the shadow color, so plot floors turned black.

  • Examples: the Swift Charts 3D corpus moved to Examples/04_Workflows/Swift and is found by its first sample wherever the package is installed; the Swift Charts 3D Import scene pairs native Swift renders with live imported charts and pages, imports and copies them in the Inspector.

  • Examples: 05_ProductionExamples/Charts in a Game World is a greenhouse level seen from a fixed game camera, with a small 3D bar chart of each raised bed’s monthly harvest on a stake beside the bed and a screen-space HUD ranking the beds. CropBed is a custom Chart Data Source with a stated crop model: each crop’s harvest follows a logistic curve in the hours of daylight since planting, read from the Daylight Hours data at the bed’s latitude; HarvestRanking ranks the beds by season harvest and ranks again whenever a bed publishes.

  • Examples: 05_ProductionExamples/Sound Spectrogram draws the live spectrum of a clip synthesized for the example as a waterfall surface on a log frequency axis that scrolls while the clip plays, with the newest spectrum and a play and pause button on the paper card, which hangs on a rail at the table’s front edge below the floor labels. AudioSpectrogramSource is a custom Chart Data Source: it reads Unity’s FFT of an AudioSource, folds it into log-spaced bands in decibels and writes each slice into its published frame in place (OverwriteValues and PublishValueChange), so the waterfall updates its surface without compiling and keeps its colors from the floor to 0 dB, and outside Play Mode it shows a preview of the same shape.

  • Examples: 05_ProductionExamples/Terrain Survey shows the earthquakes beneath Mount St. Helens from September to December 2004 (USGS ComCat, located by the Pacific Northwest Seismic Network) through its translucent terrain, sized by magnitude over a narrow symbol size range and colored by month inside a box from 2,000 m below sea level, with a level plane that a slider on the paper card moves; the card hangs on a rail at the table’s front edge below the floor labels and plots the share of the map below each height and gives it in words. TerrainSurvey composes the chart’s rows from the terrain and quake data assets and replaces only the plane’s row as the level moves, which the charts take in place through SetData(frame, shapeChanged: false).

  • Examples: the numbered tracks from 00_Entry to 04_Workflows replace the earlier samples, each scene a saved table of charts with real data. The Showcase, AnimatedSurface, Morph2Dto3D, SpatialGlassOrbit, Scene 30 Swift browser and Linked 2D and 3D Showcases scenes and their scripts are retired, Examples/SampleCoverage.md records where each went, and the Welcome card’s Open Showcase opens 00_Entry/Chart Guru 3D Showcase.

  • 3D points draw the Symbol channel as 2D charts do: a symbol column keys each point by its category, the chart’s symbol scale maps keys, keys without an entry take spheres, cubes, cones and cylinders in the order they appear, a symbol set on the point or by its layer wins over that automatic symbol, and literal symbol cells are the points’ own symbols. Added PointMark3D.Symbol(PlottableValueRef) and Chart3DBuilder.ChartSymbolScale, which generated C# writes. 2D shapes without a solid of their own, such as diamonds and crosses, now draw as cylinders instead of spheres, in symbol scales, layer styles and .Z() lifts alike.

  • Chart3DImage and Chart3DElement draw the chart’s title and subtitle like 2D charts in UI, at the top or bottom edge on the view’s background, and their view frames the chart clear of the title block. A Chart 3D host in the scene stays untitled.

  • Date columns work on every 3D axis: an axis that reads dates counts seconds from its own earliest date and labels its ticks with dates, so a date on Z, such as the Treasury yield surface’s, no longer ticks raw epoch seconds, and date cells on Y, X End, Z Start and Z End no longer drop their rows.

  • Added Chart3DCaptureOptions.OverridePose, Pose and Projection, so a capture prints a chart from a chosen view without turning it.

  • Auto Rotate of Chart3DImage, Chart3DTexture and Chart3DElement turns the view in Play Mode only; Edit Mode draws the initial pose once and stays quiet.

  • 3D axis titles follow the new AxisConfig.ShowTitle, so a hidden title still names its axis in tooltips.

  • Explicit scale ranges (ChartXScaleRange and the like) are in Swift’s plot units, in which the automatic range spans -0.5 to 0.5, so they scale with the host’s plot size like automatic ranges: Swift’s range: -0.65...0.65 spans 1.3 plot widths instead of 1.3 meters on any host.

  • Runtime offscreen charts initialize label geometry before fitting the first view. Previously, newly created labels could contribute uninitialized text bounds and zoom the chart out to a blank image.

  • Offscreen 3D cameras assign Camera.scene only for editor preview scenes. Player outputs retain their isolated layer without passing an unsupported runtime scene to Unity’s preview-scene filter.

  • The 3D compiler reads a constant Series value of a layer, the series name Chart Guru definitions can now give a whole layer, so the marks of such a layer share that name in 3D charts as well.

  • The Linked 2D and 3D Showcases sample opens without TextMesh Pro warnings and without stored label objects. Its six bold captions asked for an ellipsis, which TextMesh Pro cannot provide for bold text of a font without a bold typeface, so each one logged a warning and was truncated anyway; they now truncate directly. The scene and its prefab also held 38 label objects that the two companion charts rebuild on start, and the companion charts are saved in the Chart Guru 1.4 layout.

  • Chart3DImage and Chart3DTexture host their own chart like any chart host (IChartHost): a new component starts in Chart3DContentMode.Own with a 3D bar definition that shows preview data, takes an inline definition or a chart asset plus a data asset or data source, and runs its own transitions, while Source mode mirrors a scene Chart 3D host; inspectors and Swift paste treat both as 3D chart hosts.

  • Chart3DElement draws its tooltips with Chart Guru’s UI Toolkit tooltip presenter, which now serves any UI Toolkit host and draws no 2D plot guide for 3D hits.

  • The 3D Gallery lists chart templates from Editor/Gallery/Templates on Chart Guru’s gallery view, with the same badges and card actions, live tiles in each template’s pose, projection and theme that turn under the pointer only with Rotate on Hover, and a large preview that orbits like every 3D output and switches pose, projection and theme without changing the template; Create in Scene goes through the shared 3D placement. Removed the runtime preview registry, Chart3DPreviewAttribute and the preview builder classes.

  • The Chart Designer’s 3D mode replaces the 3D Designer window and Tools/Chart Guru/3D Designer: a pose and projection strip under the preview, a Camera and Look drawer with the angles, distance, framing, shadow plane, environment, material preset and Save Image, a preview that orbits on drag and saves the angle as one Undo step, zooms on scroll and frames on double click, and Surface function and Material rows in the tabs. Open in Designer from the 3D Gallery lands in 3D mode.

  • Convert to 3D Chart and Convert to 2D Chart in the chart inspectors replace a chart on a world-space Canvas with a 3D chart and back as one Undo step, keeping its chart, data, name and place; the chart type maps to its 3D or 2D form and a new 3D chart lifts out of its flat drawing. The Chart Designer lifts the chart when it switches to 3D, flattens it before switching to 2D and replays the lift with Lift from 2D. The box templates, Nested Volumes and Volume Clusters, moved to the Chart Guru extension marks as rectanglemark and rectanglemark-volume-clusters, because Swift Charts 3D rectangles span only two axes.

  • A 3D chart shown through Chart3DImage or Chart3DTexture limits its view texture to 4096 pixels on the longest side and keeps the aspect ratio. A large rect on a canvas with a high scale factor asked for a texture beyond the render texture limit, for example 28626 x 21401, and the view logged “RenderTexture.Create failed” every frame.

  • The Surface shader carries stereo eye data for Single Pass Instanced XR, and the offscreen camera of a chart output is excluded from stereo rendering on the Built-in Render Pipeline.

  • Declare Unity 6.7 lifetimes for stateless definition compiler/editor services and reset the non-instanced draw override through generated cleanup while retaining the earlier subsystem reset.

  • Added guarded Unity 6.5+ Play Mode qualification for Chart3DElement in an actual world-space PanelRenderer, including scheduled rendering, visible texture readback, pointer orbit, retained-tree re-enable and detach cleanup; documented the existing host-independent backend and UIDocument sample compatibility.

  • Guarded the 3D inspector’s scheduled pointer setup hint against destroyed chart components so deleting a chart or removing its component does not throw MissingReferenceException during refresh.

  • Every Canvas and UI Toolkit output renders through its own private view (a chart host bound once with its own camera and lights on the isolated preview layer) and renders only when the chart’s content, highlight, pose, theme, options, size or a running transition changed, rendering the camera alone for pose and zoom changes. Chart3DViewSettings.RefreshHz defaults to 0 and only serves content that changes without telling the chart, so unchanged outputs no longer render or allocate every frame and outputs of different charts no longer re-bind one shared host.

  • Added Chart3DElement, a UI Toolkit 3D chart ([UxmlElement], with a UXML factory on Unity 2022.3) that hosts an inline definition or a chart asset with a data asset or source, renders through its own view, runs its chart’s transitions, and orbits and zooms through the shared pointer path.

  • Chart3DImage takes Canvas pointer events through the shared interaction controller, so drags orbit the shown pose, scrolling zooms its view and a double tap restores the home pose; Chart3DTexture stays a non-interactive texture.

  • Added Chart3DComponent.Capture and CaptureToPng with Chart3DCaptureOptions (size, supersampling up to 4x, transparent background) that render a host’s chart with its presentation, pose, projection and theme without touching the host, and an editor PNG export that writes through the AssetDatabase and asks before replacing a file.

  • Replaced the static Chart3DLegendModel.Resolve with a reusable Chart3DLegendModel that resolves legends with the 2D rules (keyed by foreground style, else by series, with shared explicit colors, foreground style scales, legend item callbacks and color-scale keys) and allocates nothing once warmed. Title and annotation models with leader lines prepare legends, titles and annotations for 3D hosts, and hover and selection no longer rebuild the mark color engine.

  • Height- and normal-based surfaces follow the theme’s HeightColormap and NormalColormap, evaluated exactly from the published viridis, magma, plasma, inferno, cividis or turbo table; Custom keeps the theme’s gradients.

  • Examples ship compact public datasets as data assets (Mauna Loa carbon dioxide, ERCOT generation mix, Mount St. Helens terrain, Tonga earthquakes, Treasury yield curves, Palmer penguins and computed daylight hours) with a credit README, plus a shared studio stage kit for the samples.

  • The editor checks the installed Chart Guru version on load, from its own assembly that compiles without Chart Guru, and when it is older than 1.4.0, the minimum this add-on requires, logs one error naming both versions and once per session offers to open the Package Manager; the check stays silent when the base package cannot be located.

  • package.json declares the Input System the examples use, matches Chart Guru’s versions of shared Unity packages and links the add-on’s website, documentation and changelog, and ThirdPartyNotices.md covers the Unity packages, the Palmer Penguins dataset and the Swift Charts reference images.

  • 3D charts take pointer input through a ChartRaycaster on the camera, which the 3D menus, Gallery and Designer add with each chart and the inspector offers: hover shows tooltips, a tap selects the mark and the X, Y and Z values under it (in the empty plot volume too, like chartZSelection), drags orbit the pose and scroll or pinch zooms. Without a camera rig a chart shows its pose by turning a hidden content child about the plot center, so pose changes keep the data geometry and the host needs no MeshFilter or MeshRenderer; the legacy 3D interaction controller component, which read Unity’s legacy Input, is removed.

  • Literal Size channels set 3D point diameters in points, matching 2D charts.

  • 3D bars and areas include zero in their Y domain like their 2D forms, so the smallest bars no longer collapse onto the domain floor and vanish.

  • 3D charts use Chart Guru’s ChartTheme: its Appearance3D block sets lighting, ambient light, environment, materials, color maps, surface resolution, 3D strokes, labels and the shadow plane, hosts draw with their definition’s theme (charts built in code with Chart3DBuilder.Theme), and Chart3DSnapshotOptions, Chart3DImage and Chart3DTexture take a ChartTheme plus an optional Chart3DAppearanceOverride that swaps the environment cubemap for one output. Removed Chart3DTheme, Chart3DThemeRegistry, Chart3DBuiltInThemes, Chart3DThemeEditor, Chart3DComponent.Theme3D, Chart3DBuilder.Theme3D and the snapshot EnvironmentCubemap option, and dropped theme fields nothing read (BarMaterial, DefaultSurfaceStyle, TickProjectionOpacity, DefaultPose, DefaultProjection); snapshot renders no longer register, clone or change a chart’s theme.

  • Rebuilt Chart3DComponent on the shared Chart Guru host: it holds an inline ChartDefinition or a ChartAsset with an optional data asset or source, compiles definitions into 3D marks through Chart3DDefinitionCompiler (2D chart types extrude and several value columns become Z lanes) and shows code-built charts through SetChart. RebuildMeshes rebuilds meshes immediately while Rebuild recompiles the definition. Removed IChart3DHost, the Chart setter, the data source bridge and the component’s mark, mapping and style fields.

  • The 3D inspector is the shared chart inspector with the 3D host’s rows in its sections: pose, projection and the camera rig under Camera, plot size, materials, axes, shadow plane, environment and timing under Output, Export PNG through Chart3DCaptureExport under Export, and diagnostics with Rebuild Meshes under Advanced. Chart Type lists 3D types only, and the Chart Raycaster hint follows scene changes instead of polling. The 3D Gallery, Designer and menu items save charts as inline definitions.

  • GameObject/Chart Guru/3D/Surface, Points and Bars and the Welcome card’s Create 3D Chart place charts through one helper (Chart3DSceneCreation): at the Scene view pivot or under the selected object, with a key light only when the scene has none, an EventSystem and Chart Raycaster, and a saved copy of the definition, framed and selected as one Undo step. The add-on registers with Chart Guru’s editor through one Chart3DEditorAddOn class, adds a 3D Gallery button to the main toolbar and offers Open Showcase, 3D Gallery and Create 3D Chart on the Welcome card. Its components and examples moved from Add Component > ChartGuru to Add Component > Chart Guru.

  • The Chart 3D Image and Chart 3D Texture inspectors follow the Content mode: in Own mode they are the shared chart inspector with the output’s camera, look and quality settings under Camera and Output, and in Source mode they pick the scene Chart 3D to mirror and say when none is assigned. Switching to Own clears the source in the same Undo step. GameObject/UI/Chart Guru/3D Chart puts a Chart 3D Image that hosts its own bar chart on a Canvas as one Undo step.

  • Compiled 3D definitions label category, date and depth-lane positions on their axes instead of indices and seconds, layers share category positions, and a category or date X spreads further value columns over labelled depth lanes instead of reading them as Z coordinates.

  • Charts set from code keep their chart type, so a 2D chart is drawn flat and can be lifted with a morph; 3D layer styles apply per layer and keep per-point sizes from a Size column; Rule3D layers read X End; a numeric X keeps a lone category as the series; the gallery writer keeps a shared tint as a fixed layer color; and the Spatial Glass orbit and showcase samples detect their own charts instead of counting marks.

  • Renamed the third built-in look to Spatial Glass, now the Runtime/Theme/SpatialGlassTheme.asset theme that the theme inspector and 3D Designer offer as a preset, and its orbit sample to SpatialGlassOrbit (Chart3DSpatialGlassOrbit), keeping the sample’s asset GUIDs, so theme and sample names avoid platform trademarks.

  • Restricted the Swift importer to Apple’s Chart3D API: pseudo-Swift marks (BarMark3D, LineMark3D, AreaMark3D, ScatterMark3D, SectorMark3D, DonutMark3D, RadarMark3D), 2D marks, xStart-style rule and rectangle bindings, function: .name and non-numeric bindings now fail with errors, and pseudo modifiers (.chartType, .opacity, .category, .series, .offset, .zKey, .cornerRadius, .lineStyle, .width, .stacking, .domain, .resolution, .yRange, .symbol(.billboard), symbolRotation(x:y:z:), pose distance, .solid and .gradient surface styles) are ignored with warnings instead of imported.

  • Swift Charts 3D imports go through Chart Guru’s shared Swift front end and produce a ChartDefinition: consecutive PointMark, RuleMark, RectangleMark and SurfacePlot content becomes layers that keep point sizes, colors, symbols, rotations, roughness and metalness, rule and rectangle ranges, and function surfaces with their style, gradient and height range, while chart modifiers set axes, scale types, domains, plot ranges, pose and projection. Pasting a Chart3D declaration in the Chart 3D inspector sets the host’s inline definition.

  • Chart3DDefinitionCompiler compiles each layer by its own mark, so one definition mixes 3D points, rules, rectangles and function surfaces (ChartLayer.SurfacePlot), and it reads the Z Start and Z End channels, ChartLayerStyle3D and the definition’s X, Y and Z plot ranges.

  • Surface layers whose function is written in Chart Guru’s Swift expression subset, such as an imported SurfacePlot closure or sin(x) * cos(z) typed in the inspector, evaluate live through a compiled evaluator that runs in double precision without allocations, reflection or generated code, so it works on IL2CPP, and generated C# writes them as Mathf lambdas. The layer inspector’s Function row shows why its text draws nothing, such as the parser’s error, instead of naming a function it cannot draw. Chart3DSurfaceFunctions keeps only the eight shapes the Designer offers; the Swift pie and donut samples now write their sectors as closures.

  • Scene 30 adds seven Swift Charts 3D samples with native iOS 27 captures, covering keyed points with a style scale, a data initializer, the front pose with AxisMarks, a closure surface with a $pose binding, a log scale with chartZSelection, a hidden Z axis with title options, ForEach with a conditional and a declared surface function. Generated C# writes pose presets such as Chart3DPose.Front.

  • Replaced Chart3DCodeGenerator with Chart Guru’s definition code generator: 3D Designer export and the Scene 30 browser write Chart3D builder code from the definition without restating defaults, and the 3D Designer names the exported class after its file.

  • Isolated snapshot and Canvas preview renders on a private unnamed layer shared by the preview camera, its lights and the whole preview hierarchy, so player-build snapshots no longer capture scene geometry or lights and scene charts no longer react to preview cameras.

  • Rendered Symbol3D.Billboard points as sphere-sized flat discs that face each camera (submitted from the BRP/SRP camera callbacks and the preview camera path) instead of spheres.

  • Generated C# no longer emits Symbol3D.Custom for points whose custom mesh it cannot export; it writes the sphere the runtime draws without a mesh and a comment naming the mesh to reassign.

  • Mixed charts now sample a SurfacePlotMark without its own domain over the same X/Z scale domain its mesh uses, so the inferred Y domain covers the rendered surface, the mesh reuses the inference samples, and the surface no longer widens other content’s domain with its default (-1, 1) range.

  • Skipped marks with a non-finite coordinate whole in both domain inference and mesh building, kept all-undefined surfaces from adding a phantom Y range, and made PlottableValueRef 3D coordinates report non-numeric values with the mark, argument and value instead of a conversion exception.

  • Referenced the 3D Vertex Lit, Vertex Unlit and Surface shaders from a cached Chart3DShaderResources Resources asset, with GPU-instancing materials that keep instancing variants, so player builds include them; Shader.Find for package shaders remains only as an editor fallback beside the URP/HDRP fallbacks.

  • Rebuilt the 3D Vertex Lit and Vertex Unlit shaders on shared HLSL includes with URP, HDRP and Built-in programs: URP keeps one forward-only color pass that every rendering path and the 2D renderer draw and adds shadow caster, depth, depth-normal and, on URP 17, motion vector passes; HDRP programs keep vertex and instance colors with exposure-invariant studio lighting and forward, depth, shadow and motion vector passes; Built-in adds a shadow caster that also writes the camera depth texture. Colors and lighting are unchanged with the default lighting values.

  • Declared every 3D shader input in one UnityPerMaterial layout shared by all passes, with GPU and DOTS instancing in every URP and HDRP pass and single-pass stereo instancing, so the shaders are compatible with the SRP Batcher, BatchRendererGroup and the GPU Resident Drawer. _ChartLightRotation selects world, content or object space for the studio lights, _ChartTransitionT and _ChartTransitionPrevT are reserved for transitions, and motion vectors read the previous position from TEXCOORD4.

  • Added guard tests for the pass inventory, material layout, instancing, stereo and HDRP contracts of the 3D shaders, and Metal compilation tests for every pass and keyword variant of the active pipeline.

  • 3D hosts draw their meshes with their own material clones that carry the studio lighting in object space instead of renderer property blocks, so turning a chart writes no material state and chart meshes stay compatible with the SRP Batcher and the GPU Resident Drawer; HDRP projects draw with the package shaders, transparent variants switch blending without keywords, and point symbols draw one by one with the same shading where GPU instancing is unsupported.

  • Every camera, the Scene view and second cameras included, now sees the axis walls, edges and labels of its own side: hosts build the axis chrome for every viewpoint and each camera picks its part, so orbiting or crossing walls no longer rebuilds or allocates, axis and grid lines draw as instanced cylinders, and blended triangles keep a back-to-front copy per camera instead of re-uploading when cameras take turns.

  • 3D charts write their geometry with Burst jobs into native buffers and upload only the streams that changed; default bars, point symbols and thin rules draw as GPU instances, hover and selection recolor the chart without rebuilding it (hover highlight is now on), and custom marks add geometry through Chart3DMeshContext.AddTriangles and AddInstance. The public Chart3DMeshRegistry, Chart3DComponent.Registry and DrawInstancedToCamera were removed; every camera that renders a chart, Camera.Render included, draws its instances itself.

  • Taps, hover highlight and tooltips in Canvas and UI Toolkit outputs pick marks through the output’s own camera.

  • Moved the Scene 30 browser inspector into a separate ChartGuru.3D.Examples.Editor assembly; ChartGuru.3D.Editor no longer references the Examples assembly, so the 3D editor tooling compiles without the examples.

  • Moved the Scene 30 compile-and-render parity tests that need Chart Guru Debug into a separate ChartGuru.Debug.3D.Editor.Tests assembly so ChartGuru.3D.Editor.Tests compiles in package-clean lanes.

  • Declared static showcase datasets and immutable fit caches as metadata retained across Play sessions on Unity 6.7.

  • Keep the flattened numeric bar projection nonzero so 3D bar geometry, stacking, labels, and hit testing retain their canonical world-space footprints.

  • Use the shared window layout in the 3D Designer so scrolling tab content reaches the window edge.

  • Corrected perspective tick-collision and axis-title spacing using depth-normalized text bounds and deterministic label-aware framing, with shallow/front/overhead/rear camera regressions and allocation-free moving-camera coverage.
  • Matched tolerance-showcase tick formatting to native whole-number labels, preserving clear corner-label spacing in standalone and linked quality views.
  • Themed linked-showcase controls and dropdown items consistently in light and dark modes, corrected panel sprite import and responsive selection-thumb bounds, and added persisted-gallery Play Mode coverage for linked selection, pixel-density changes and reactivation.
  • Recreated all approved native showcase compositions with Chart Guru marks, shared 2D companions, stable-identity point links, unit-aware slice selection and explicit chart ownership; retained sampled surfaces during linked updates.
  • Added immutable native showcase measurements, FFT fixtures, catalog metadata and shared C# response functions with hash-checked regeneration and native checkpoint, regression, stack, histogram and missing-data tests.
  • Added the native visual-review bundle with 24 showcase proposals, eight alternate states, raw/cropped captures, deterministic recreation data, hash verification and explicit native limitations; accepted Scene 30 references remain unchanged.
  • Shortened the native housing-distance axis title and clarified its caption to avoid the neighboring floor-area tick at the review angle.
  • Corrected native review histogram geometry, quarter labels and dark tick contrast; cached derived datasets and exported units, stack bounds, bins and activity cells with raw-image/data hashes and capture safety checks.
  • Calibrated native showcase rectangle compositions against offset-domain XY/YZ/XZ probes; added explicit shared palettes, category keys, reproducible capture locale, and composition checks while preserving raw native fixtures.
  • Added an isolated native Swift showcase review app with typed real/demo datasets, reusable 3D compositions, coordinated 2D panels, numerical preflight checks, source-matched simulator capture, and review manifests without modifying the accepted Scene 30 corpus.
  • Reused the 2D gallery’s shared compact toolbar, full-width cards, keyboard selection, and responsive styling; replaced the permanent detail pane with an on-demand hero preview, retained explicit scene/export actions, consolidated visibility polling, and corrected empty-token filtering and package-relative documentation links.
  • Corrected layout-backed bar widths, canonical nonlinear/inverted world-scale projection, automatic footprint bands, stack domains, normalized negative values, animated heights, and face-anchored labels; authored explicit proportions for mixed-unit gallery bars and ribbons.
  • Added per-camera transparent mesh triangle ordering with reusable centroid/index storage, unchanged-view upload avoidance, and rendered front/back blending regression coverage.
  • Matched native Swift scale-modifier precedence, kept combined domain/range/type settings intact, and added independent native probes for scale ordering and nonfinite surface boundaries.
  • Added bounded boundary refinement and native domain-edge walls for function surfaces, preserving undefined interiors, split cap/wall normals, analytical styling, explicit open boundaries, cloning, and generated C#.
  • Consolidated Canvas image and texture outputs on a shared, DPI-aware renderer with serialized source binding, chart/manual camera selection, theme/custom backgrounds, explicit invalidation, loading-thread-safe defaults, and owned render-target cleanup.
  • Rebuilt Scene 30 with matched live/native image panels, clipped scrollable C#/Swift source, runtime sample navigation, a generated chart catalog, and fresh native iOS captures; opening the browser inspector no longer creates scene-save prompts.
  • Removed incomplete runtime-chart graph serialization from 3D hosts and retained native automatic camera distance when importing poses without an explicit distance.
  • Released generated 3D hierarchy children without reparenting during activation, including same-frame disable/re-enable and Play Mode exit.
  • Unified live-preview supersampling with CPU snapshots, added themed preview backgrounds and explicit manual orthographic sizing, and made the Designer honor camera controls without losing automatic framing when an angle changes.
  • Added editor-time gallery visibility, fair render scheduling, revision/option invalidation, chart disposal, and reload cleanup; bounded unused render textures by count and estimated bytes without reducing active target resolution.
  • Improved high-DPI and responsive Designer/Gallery previews, preserved readable preview status contrast, separated native rectangle planes from extension volumes, and cleared stale instanced geometry and labels when removing a chart.
  • Corrected sRGB vertex/instance color decoding, implemented per-host theme lighting and environment reflections, separated theme material defaults from explicit presets, and released generated materials/themes on editor reload.
  • Matched height-color normalization to native automatic plot proportions, added a spectrum height palette, and made default normal coloring distinguish X/Z orientation and visible surface sides while retaining custom slope gradients and independently controlled analytical lighting.
  • Removed shared CPU snapshot ownership and incomplete content hashes; snapshots are caller-owned, PNG/orbit failure paths release intermediates, and designer previews use chart revisions and theme dirty versions.
  • Rendered axis/grid strokes with theme-controlled plot-space widths, honored theme line materials, aligned snapshot perspective with live cameras, separated titles from measured tick-label bounds, and respected automatic/greedy collision handling, disabled collision handling, and explicit tick-label orientation.
  • Added optional native data-proportional plot ranges, camera-space framing, readable automatic tick steps, and calibrated sphere/cylinder/cone sizes, origins, normals, and symbol rotations against native Swift Charts captures.
  • Converted native Swift depth coordinates consistently across geometry, axes, and selection; axis frames now follow explicit ranges, with near-edge floor labels, silhouette Y labels, and working camera-facing text.
  • Reused preview-host meshes and labels without changing caller pose, theme registration, or pending dirty flags; camera fitting now includes symbols and labels, and built-in themes reuse owned instances.
  • Corrected camera inclination and host-relative orbit/dolly behavior, including explicit pose distances, and made Scene 30 captures use each sample’s actual pose and projection with timestamped outputs.
  • Added parameterized X/Y/Z scale APIs and reused canonical scale instances across layout-backed bars, mesh geometry, axes, labels, and interaction.
  • Reused sampled surface buffers and the first domain-inference sampling pass, bounded surface resolution and instanced batch storage, and retained flattened layouts only for mark families that require them.
  • Added per-mark metalness and roughness to mesh and instanced shader payloads, with opaque/transparent draw partitioning and owned material variants that do not modify source assets.
  • Added explicit ownership and cleanup for native meshes, temporary materials, camera helpers, shadow planes, and scene-wide environment overrides.
  • Updated the native Swift Charts 3D corpus to compile against Apple’s API and added native-source type checking to Scene 30 validation.
  • Preserved custom height gradients, directional foreground gradients, sampled surface grids, and designer surface presets in generated C#; unsupported surface delegates and imports now report errors instead of silently substituting a wave.
  • Replaced line-only area rendering with closed two-sided 3D area volumes, including standard, normalized, centered, and unstacked multi-series area geometry.
  • Chart3D builders now reject 2D marks and retain the first primary 3D mark type when later rule overlays are added.
  • Unified 3D geometry, axes, labels, and hit testing on canonical configured scales with explicit-domain, inversion, custom-tick, and axis-visibility support.
  • Published native 3D compiler snapshots directly so domain queries no longer trigger an unrelated 2D layout pass.
  • Added a core data-only 3D mark contract so selection, accessibility descriptors, audio graphs, and semantic exports can consume X/Y/Z values without depending on the optional 3D renderer.
  • Added Unity 6.7 lifecycle ownership for preview, mesh, theme, and gallery caches while retaining Unity 2022.3 support.
  • Moved the Scene 30 builder and parity and visual validators into a nested Chart Guru Debug assembly while retaining a customer browser without internal QA actions or dependencies.
  • Updated the Morph 2D to 3D sample keyboard control to use Unity’s Input System while keeping the runtime interaction compatibility component independent.
  • Reduced scripting clutter by keeping 3D layout, mesh generation, preview, cache, and job infrastructure internal.
  • Rebuilt all 3D chart inspectors, drawers, galleries, welcome screens, and the 3D Designer with polished responsive UI Toolkit layouts and live previews.
  • Reorganized 3D inspector settings into focused, neutral sections with clearer tooltips and progressive disclosure.
  • Clarified Swift Charts 3D parity versus ChartGuru-only 3D extensions.
  • Split 3D scale APIs into explicit chartXScaleDomain / chartYScaleDomain / chartZScaleDomain and chartXScaleRange / chartYScaleRange / chartZScaleRange methods.
  • Preview rendering now applies axes, shadow plane, and environment options through the shared render scene and restores temporary state after every render.
  • Implemented per-mark Metalness, Roughness, and rounded Bar3DMark geometry alongside theme-level material controls.
  • Removed the obsolete ChartGuru/3D Surface URP shader; the active 3D material path now uses the cross-pipeline vertex-lit shader or SRP-native fallbacks.
  • Added an authoring guide covering setup, chart type choice, scale semantics, render pipelines, and interaction.
  • Preserved stacked-area types and stacking methods through data-source generation, authoring styles, cloning, domain calculation, and generated C#.
  • Split sector cap, wall, and radial-edge vertices so lighting uses face-correct normals at every hard edge.
  • Preserved concrete 3D mark subtypes and complete shared styling, semantic, annotation, and depth state when cloning marks.
  • Computed sampled-surface normals from geometry, preserved nonfinite holes, and kept YRange as a Swift-equivalent height-color range with separate explicit ClampY geometry clipping.
  • Corrected inverted rectangle/surface geometry, radar scaling and colors, sector radius bounds, and segment-based line/area selection without synthetic-anchor fallbacks.
  • Rule width now creates rendered tube geometry instead of storing a silent no-op value.
  • Instanced symbol drawing reuses batch arrays and material property blocks instead of allocating per draw page.
  • ChartGuru-only Bar3D gradient preview metadata is no longer labeled as Swift parity.
  • 3D click selection now chooses the nearest projected mark and updates X, Y, Z, and selected index together.
  • Inspector and gallery previews now render a compact overlay legend from foreground style or series keys.
  • Initial release of the com.wetzold.chart-guru.3d package.
  • Chart3D fluent builder with Swift-Charts-shaped API (Chart3D.Create(), chartZAxis, chartZScale, chart3DPose, chart3DCameraProjection).
  • Swift parity marks: PointMark3D, RuleMark3D, RectangleMark3D, SurfacePlotMark with .heightBased, .normalBased, foregroundStyle, and sphere/cylinder/cone symbols.
  • 3D extensions of ChartGuru chart types: Bar3D, Line3D, Area3D, StackedArea3D, Pie3D, Donut3D, Radar3D, Scatter3D. Grouped and stacked 3D bars are controlled through stacking modifiers on Bar3D.
  • Burst-compiled mesh pipeline: SurfaceMeshJob, ExtrudeMeshJob, InstancedSymbolJob.
  • ChartGuru3DSurface shader with BRP/URP/HDRP variants driven via MaterialPropertyBlock (height-based, normal-based, metalness, roughness).
  • Chart3DComponent world-space mesh host with orbit/dolly/zoom camera rig, shadow plane, HDR environment.
  • Pointer interaction through ChartRaycaster: drag to orbit, scroll or pinch to zoom, double-tap reset, ray hit testing with tooltips and chartZSelection wiring.
  • 2D↔3D morph recipes: Bar↔Bar3D, Line↔Line3D ribbon, Area↔Area3D prism, Pie↔Pie3D, Scatter↔Scatter3D, Surface↔Heatmap.
  • 3D looks from the Appearance3D block of Chart Guru themes, with Default, Dark and Spatial Glass looks.
  • Editor tooling: Chart3DComponentInspector, Chart3DPoseDrawer, Chart3DGalleryWindow, Chart3DDesignerWindow and Chart3DCodeGenerator.
  • Samples: Showcase, Morph2Dto3D, SpatialGlassOrbit, AnimatedSurface.