Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Until now, the only way to show a Chart4D plot on screen, with its cached render, hover highlight and tooltip, was the
TChart4Dcontrol. An application that already owns a canvas had to either reimplement that logic or give up hover and tooltips. A typical case is a VCLTPaintBoxin an existing viewer.This PR adds
TChartPainterto bothChart4D.VCLandChart4D.FMX. It paints anyTChartPlotonto a canvas the caller supplies, with the same buffering, hover tracking and tooltip as the control:When the chart shares the canvas with other content, it can be painted into a rectangle instead. It is laid out for that rectangle's size, and nothing is drawn outside it:
Pointer moves and leaves go to
FPainter.MouseMoveandFPainter.MouseLeave.MouseMovetakes canvas coordinates, and a position outside the painted rectangle counts as leaving the chart.FPainter.ViewcarriesShowTooltipsandOnDataPointHover.Design
The framework-neutral part is in the new RTL-only unit
Chart4D.View.pas, asTChartView. It references a plot without owning it and subscribes toOnChanged. It tracks whether the last render is still valid, including its size, and owns theTChartHoverState. It renders only when needed, draws the tooltip overlay, and firesOnDataPointHoverandOnRepaintRequestwhen the hovered point changes. It works in chart-local coordinates and holds no pixels, because the RTL has no bitmap class andIChartCanvascannot draw bitmaps.Each framework's
TChartPainterowns a view and the back buffer: aVcl.Graphics.TBitmapdrawn throughTGdiPlusChartCanvas, or anFMX.Graphics.TBitmapdrawn throughTFmxChartCanvas. It has twoPaintoverloads:Paint(Canvas, Bounds), with aTRectin the VCL and aTRectFin FMX. It resizes the buffer to the size ofBounds, renders when needed, copies the buffer toBoundsand then draws the overlay, shifted toBounds.TopLeftand clipped toBounds. The clip matters: a tooltip pushed against the chart edge strokes its border across that edge, which would otherwise mark the neighbouring content.Paint(Canvas, Width, Height), which is the same asPaintwith bounds(0, 0, Width, Height).Both overloads raise
EChart4DExceptionfor a negative width or height.The painter remembers the painted bounds, so
MouseMovetranslates canvas coordinates into chart coordinates. Outside the bounds it reports leaving, since a hit target with a radius could otherwise be hit from just outside the chart.The painter does not own the plot and takes over
Plot.OnChanged. When destroyed, it clears that handler only if it hasn't been reassigned since.TChart4Dnow uses the painterTChart4Din both frameworks is now built on its painter, painting at its own origin. It still owns its plot, and passesPaint,Resizeand the mouse events on to the painter. The two controls were near line-for-line duplicates (FHover,FBackBuffer,EnsureBackBuffer,DrawTooltipOverlay,PlotChanged,HoverChangedand the mouse handlers). That logic now lives once in the core, asTChartHoverStatealready does (SPEC 4.11), so the controls cannot drift apart. Only the back buffer, the canvas adapter andInvalidateversusRepaintstill differ.Compatibility
The public and protected API of
TChart4Dis unchanged:Create,Destroy,SaveToPng,Plot,ShowTooltips,OnDataPointHover, the published properties, FMX'sPaint, andRenderChartToBackBuffer. So is its behaviour: repaint onPlot.OnChanged, a resize invalidates the buffer,OnDataPointHoverpasses the control asSender, andSaveToPng(untouched) never draws a tooltip and raises on an empty plot.Docs
SPaintBoundsNegativeSizemessage), 4.9, 4.10, 4.11 and the test list in section 5 are updated.Tests
New fixture
Chart4D.View.Testswith 19 tests: render skipping and re-rendering after a plot change, size change orInvalidate; hover events and repaint requests; overlay drawn or not; unsubscribe on destroy.VclCheck and FmxCheck each have a new
VerifyPainterBoundscheck. The same painter paints once at the origin and once into offset bounds on a larger canvas filled with a marker color. The check requires that:The hovered point is the last one of a line chart, so its tooltip is pushed against the edge. Removing the overlay shift or the clip from either painter makes the check fail.
Chart4D_R(RAD Studio 12.0 and 13.0) and CoreCheck, VclCheck and FmxCheck include the new unit, and CoreCheck exercises the view.The suite passes on Win32 and Win64 (241/241 each).
The packages, demos and tools build with zero warnings and hints, and CoreCheck, VclCheck and FmxCheck pass. VclCheck and FmxCheck drive the controls through the new paint path.
🤖 Generated with Claude Code