Class Chart
- Direct Known Subclasses:
CartesianChart,DonutChart
BarChart, LineChart and
DonutChart add the marks and the axes.
A chart is usable with nothing configured: colors come from the palette that matches
the active Theme, the scale rounds itself, the legend appears when there is more
than one thing to name, and values animate in. Everything past that is a setter.
BarChart chart = new BarChart();
chart.setLabels("Mon", "Tue", "Wed", "Thu", "Fri");
chart.addSeries(ChartSeries.of("Signups", 12, 19, 3, 5, 22));
chart.addSeries(ChartSeries.of("Churn", 2, 3, 1, 4, 2));
chart.setStacked(true);
chart.onPointClick(point -> open(point.label()));
Animation. Values interpolate, not pixels: on the first appearance a series
grows out of the axis baseline, and afterwards it eases from the number on screen to the
number it was just given, so a live chart re-pushed every second reads as one moving
shape rather than as a slideshow. setAnimationDuration(double) with 0
turns it off, which is also what a chart with no scene does: a headless test or a
screenshot sees final values, never an in-between frame.
Interaction. Hovering reports the datum under the pointer; the tooltip follows
it and stays inside the chart. A chart with more than one series reports every series at
the hovered category at once (Chart.TooltipMode.INDEX), which is what makes two lines
comparable at a glance. Clicking calls onPointClick(Consumer) with the same
datum. Clicking a legend entry hides and shows its series, animating the scale and any
stack around it.
Charts are painted, not composed: a chart has no child widgets, with one exception:
DonutChart.setCenter(Widget) puts a real widget in the hole, so the middle of a
donut can hold a label, an icon or a button.
On chaining. The setters here return Chart, so a chain that starts on a
subclass cannot continue into one of that subclass's own setters:
new BarChart().setTitle("x").setStacked(true) does not compile. Configure a chart
in statements (which is how the demo scenes read anyway) or start from
BarChart.of(java.util.List<java.lang.String>, limn.components.chart.ChartSeries...), LineChart.of(java.util.List<java.lang.String>, limn.components.chart.ChartSeries...) and DonutChart.of(java.util.List<java.lang.String>, double...), which take the labels
and the series together. The alternative, redeclaring every setter in all three
subclasses purely to narrow its return type, buys one expression shape at the price of
forty methods whose documentation could only repeat their signatures.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static final recordOne row of the legend: a swatch, a name, and whether its data is currently drawn.static enumWhere the legend sits relative to the plot.static enumHow much a hover reports. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final floatHands a dimension back to the default size, theProgressBar.UNSETidiom. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionaddSeries(ChartSeries newSeries) Adds a series.protected doubleThe value a series grows out of when it first appears, and collapses to when it is hidden: where the axis crosses the plot, which is zero on any scale that contains it and the nearer end otherwise.doubleLength of the entry and value-change animation, in seconds.The panel color behind the chart, ornullwhen it paints on what is below.final intHow many categories the chart spans: the labels, or the longest series.Removes every series.protected final floatHeight of the region left after the title and the legend.protected final floatWidth of the region left after the title and the legend.protected final floatLeft edge of the region left after the title and the legend.protected final floatTop edge of the region left after the title and the legend.protected final intBumped by every change to the data or to what is visible in it.protected final doubledrawnValue(int seriesIndex, int index) The value seriesseriesIndexis drawn at right now, animation included.protected final floatelementProgress(int index, int count) protected final Stringtextshortened with an ellipsis until it fitsmaxWidth, or""when not even the ellipsis fits.The datum under the pointer, ornull.booleanWhether clicking a legend entry hides and shows its data.booleanWhether hovering shows a tooltip.label(int index) The label forindex, or""when there are fewer labels than values.labels()The category labels as they currently read, in order.labelSource(int index) The localizable value behindlabel(int), orI18nString.EMPTYpast the end: what a language change re-resolves.protected final voidDrops the legend's cached entries, for a chart whose legend is not the series list.protected List<Chart.LegendEntry> One entry per series, in palette order.Where the legend sits.protected final TextMetricsMeasures a single line with the layout ruler (agrees with whatdrawTextdraws).protected voidCalled when this widget enters a scene (attached to the tree).protected voidonHoverChanged(ChartPoint picked) Called when the datum under the pointer changes,nullwhen there is none: the hook for a chart that animates something on hover.protected SizeonMeasure(Constraints constraints) Reports the size this widget wants withinconstraints.protected voidonMouseEvent(MouseEvent event) Mouse events (bubbling); callevent.consume()when handled.protected voidWidget's own background/content, in local coordinates.protected voidonPaintOverlay(Canvas canvas) Painted after children (scrollbars, focus rings…).onPointClick(Consumer<ChartPoint> listener) Called with the datum under the pointer on a left click.onPointHover(Consumer<ChartPoint> listener) Called whenever the hovered datum changes, withnullwhen the pointer leaves the marks.protected voidonSeriesAdded(ChartSeries added) Called with a series that has just joined the chart, before anything is animated.protected abstract voidpaintContent(Canvas canvas, float x, float y, float w, float h) Paints the marks inside the region left after the title and the legend, in the chart's own coordinates.palette()The palette in force: the one that was set, or the built-in one for this theme.protected abstract ChartPointpickAt(float localX, float localY) The datum under a point in the chart's local coordinates, ornullwhen the pointer is not over the marks.protected final ChartPointpointFor(int seriesIndex, int index, double share, float x, float y) Builds aChartPointfor a datum, with the anchor the caller measured.protected final floatprogress()Overall animation progress in[0,1]; 1 means the data as it stands.removeSeries(ChartSeries victim) Removes a series; a no-op when it is not in this chart.Replays the entry animation from the axis baseline.series()The series, in the order they were added (paint and palette order).protected final ChartSeriesseries(int index) The series atindex, without copying the list, the accessor the painting and hit-testing paths use, sinceseries()allocates and both run per frame.protected final floatseriesAlpha(int index) The alpha a series is currently drawn at, folding in its hide/show fade.final ColorseriesColor(int index) The color of seriesindex: its own, or its palette slot.protected final intHow many series the chart holds, visible or not.setAnimationDuration(double seconds) Sets the animation length in seconds;0draws every change immediately.setAnimationEasing(Easing easing) Sets the animation curve (defaultEasing.EASE_OUT).setBackground(Color color) Fills the chart's box withcolorbefore anything else, rounded like a card;null(the default) paints nothing, letting the chart sit on the surface it was placed on.Sets the category labels: the x axis of a bar or line chart, the slices of a donut.setLabels(String...)from a list; the list is copied.setLabels(I18nString... values) Sets category labels that follow the UI language.setLegendInteractive(boolean value) Enables or disables hide/show on legend clicks (on by default).setLegendPosition(Chart.LegendPosition position) Moves the legend, or takes it away withChart.LegendPosition.NONE.setPalette(ChartPalette value) Pins the palette;nullhands it back toChartPalette.defaultFor(limn.components.Theme), which follows the active theme's light/dark mode.setPreferredSize(float width, float height) Overrides the natural size (360.0f x 220.0f);UNSETon either axis restores it.setSeries(ChartSeries... newSeries) Replaces every series at once.Sets a title drawn above the plot (nullfor none).setTitle(I18nString value) Sets a title that follows the UI language (nullfor none).setTooltipEnabled(boolean value) Turns the hover tooltip on or off (on by default).setTooltipFormat(Function<ChartPoint, String> format) Replaces the text of a tooltip row.Sets whether a hover reports the whole category or only the mark under the pointer.setValueFormat(DoubleFunction<String> format) Sets the tooltip value format; seeChartFormatsfor ready-made ones.protected floatHow far apart consecutive elements start, as a fraction of the animation: a wipe rather than a single pop.protected final doubleHow long a state fade lasts (hiding a series, popping a hovered mark), in seconds.title()The chart title as it currently reads, ornullwhen there is none.The localizable value behindtitle(), ornull.protected voidtoggleLegendEntry(int index) Hides or shows what legend entryindexstands for.protected final SizeTokenstokens()The tokens for the step resolved on this chart; resolve once per pass, never in a field.How much of the data a hover reports.protected ColorThe swatch color for a tooltip row.protected StringtooltipRowName(ChartPoint row) The name a tooltip row carries where reading starts, the series name by default.protected List<ChartPoint> tooltipRows(ChartPoint picked) The rows a tooltip shows forpicked.protected StringThe value a tooltip row carries where reading ends.protected StringtooltipTitle(ChartPoint picked) The heading over the tooltip rows; the category label by default.protected final voidRecomputes the title/legend/plot split.How values are written in tooltips (and, unless overridden, on the value axis).withControlSize(ControlSize size) Methods inherited from class limn.scene.Widget
acceptsTextInput, add, baselineOffset, baselineOffsetOf, caretRect, children, clipboard, clipsChildren, controlSize, cursor, declaredControlSize, declaredLayoutDirection, declaredLocale, focusArrivedByTraversal, height, hitTest, imageCursor, invalidate, invalidate, isEnabled, isFocusable, isFocused, isShowing, isVisible, layoutBox, layoutDirection, locale, localToSceneX, localToSceneY, markNeedsContainedLayout, markNeedsLayout, measure, moveChild, neutralBase, onCharTyped, onDetached, onFileDrop, onFocusGained, onFocusLost, onKeyEvent, onLayout, onPreedit, overlayPassesPointer, paintChildren, paintOutset, paintWidget, parent, remove, requestFocus, revealInView, scene, sceneToLocalX, sceneToLocalY, setControlSize, setCursor, setEnabled, setFocusable, setImageCursor, setInheritanceHost, setLayoutDirection, setLocale, setTooltip, setTooltip, setVisible, shapeText, textRuler, tooltip, width, x, y
-
Field Details
-
UNSET
public static final float UNSETHands a dimension back to the default size, theProgressBar.UNSETidiom.- See Also:
-
-
Constructor Details
-
Chart
public Chart()
-
-
Method Details
-
labels
The category labels as they currently read, in order. -
label
The label forindex, or""when there are fewer labels than values. -
labelSource
The localizable value behindlabel(int), orI18nString.EMPTYpast the end: what a language change re-resolves. -
setLabels
Sets the category labels: the x axis of a bar or line chart, the slices of a donut. -
setLabels
Sets category labels that follow the UI language. There is noListform of it (List<String>andList<I18nString>erase to the same signature), so hand a list over aslist.toArray(new I18nString[0]). -
setLabels
setLabels(String...)from a list; the list is copied. -
series
The series, in the order they were added (paint and palette order). -
addSeries
Adds a series. It takes the next palette slot unless it names its own color.- Throws:
IllegalStateException- if the series already belongs to a chart
-
onSeriesAdded
Called with a series that has just joined the chart, before anything is animated. Charts with per-series defaults of their own apply them here, so a series added after the default was set is styled like the ones that were already there. -
setSeries
Replaces every series at once. -
removeSeries
Removes a series; a no-op when it is not in this chart. -
clearSeries
Removes every series. -
series
The series atindex, without copying the list, the accessor the painting and hit-testing paths use, sinceseries()allocates and both run per frame. -
seriesCount
protected final int seriesCount()How many series the chart holds, visible or not. -
dataGeneration
protected final int dataGeneration()Bumped by every change to the data or to what is visible in it. Derived structures that are expensive to rebuild (a stack-key list walked once per bar) cache against it instead of rebuilding per frame. -
contentLeft
protected final float contentLeft()Left edge of the region left after the title and the legend. -
contentTop
protected final float contentTop()Top edge of the region left after the title and the legend. -
contentBoxWidth
protected final float contentBoxWidth()Width of the region left after the title and the legend. -
contentBoxHeight
protected final float contentBoxHeight()Height of the region left after the title and the legend. -
categoryCount
public final int categoryCount()How many categories the chart spans: the labels, or the longest series. -
palette
The palette in force: the one that was set, or the built-in one for this theme. -
setPalette
Pins the palette;nullhands it back toChartPalette.defaultFor(limn.components.Theme), which follows the active theme's light/dark mode. -
seriesColor
The color of seriesindex: its own, or its palette slot. -
title
The chart title as it currently reads, ornullwhen there is none. -
titleSource
The localizable value behindtitle(), ornull. -
setTitle
Sets a title drawn above the plot (nullfor none). -
setTitle
Sets a title that follows the UI language (nullfor none). -
background
The panel color behind the chart, ornullwhen it paints on what is below. -
setBackground
Fills the chart's box withcolorbefore anything else, rounded like a card;null(the default) paints nothing, letting the chart sit on the surface it was placed on. -
legendPosition
Where the legend sits. -
setLegendPosition
Moves the legend, or takes it away withChart.LegendPosition.NONE. -
isLegendInteractive
public boolean isLegendInteractive()Whether clicking a legend entry hides and shows its data. -
setLegendInteractive
Enables or disables hide/show on legend clicks (on by default). -
setPreferredSize
Overrides the natural size (360.0f x 220.0f);UNSETon either axis restores it. A chart in anExpandedor a stretchedColumntakes the space it is given regardless; this is the fallback for an unconstrained parent. -
valueFormat
How values are written in tooltips (and, unless overridden, on the value axis). -
setValueFormat
Sets the tooltip value format; seeChartFormatsfor ready-made ones. -
isTooltipEnabled
public boolean isTooltipEnabled()Whether hovering shows a tooltip. -
setTooltipEnabled
Turns the hover tooltip on or off (on by default). -
tooltipMode
How much of the data a hover reports. -
setTooltipMode
Sets whether a hover reports the whole category or only the mark under the pointer. -
setTooltipFormat
Replaces the text of a tooltip row. The default lays each row out in two columns (the series name where reading starts, the formatted value where it ends, so both columns swap in a chart that reads right to left), which is what makes a multi-series tooltip scannable; a formatter set here produces the whole row as one string instead.nullrestores the default. -
animationDuration
public double animationDuration()Length of the entry and value-change animation, in seconds. -
setAnimationDuration
Sets the animation length in seconds;0draws every change immediately. -
setAnimationEasing
Sets the animation curve (defaultEasing.EASE_OUT). -
replayAnimation
Replays the entry animation from the axis baseline. -
onPointClick
Called with the datum under the pointer on a left click. InChart.TooltipMode.INDEXa click anywhere in a category reports that category's nearest mark, so a thin line is as clickable as a fat bar. -
onPointHover
Called whenever the hovered datum changes, withnullwhen the pointer leaves the marks. Fires on changes only, not on every pointer move. -
hoveredPoint
The datum under the pointer, ornull. -
withControlSize
-
paintContent
Paints the marks inside the region left after the title and the legend, in the chart's own coordinates. Grid, axes and everything data-shaped belong here. -
pickAt
The datum under a point in the chart's local coordinates, ornullwhen the pointer is not over the marks. Called for hover and for clicks, so it decides both. -
tooltipRows
The rows a tooltip shows forpicked. The default isChart.TooltipMode.INDEX-aware: every visible series at the same index, or just the picked datum inChart.TooltipMode.POINT. -
tooltipTitle
The heading over the tooltip rows; the category label by default. -
tooltipRowName
The name a tooltip row carries where reading starts, the series name by default. -
tooltipRowValue
The value a tooltip row carries where reading ends. -
tooltipRowColor
The swatch color for a tooltip row. -
legendEntries
One entry per series, in palette order. Overridden by charts whose legend is not that. -
toggleLegendEntry
protected void toggleLegendEntry(int index) Hides or shows what legend entryindexstands for. -
legendChanged
protected final void legendChanged()Drops the legend's cached entries, for a chart whose legend is not the series list. -
onHoverChanged
Called when the datum under the pointer changes,nullwhen there is none: the hook for a chart that animates something on hover. The application-facing callback isonPointHover(Consumer); this is for subclasses. -
updateRegions
protected final void updateRegions()Recomputes the title/legend/plot split. For a subclass laying out inonLayout. -
animationBaseline
protected double animationBaseline()The value a series grows out of when it first appears, and collapses to when it is hidden: where the axis crosses the plot, which is zero on any scale that contains it and the nearer end otherwise. -
staggerFraction
protected float staggerFraction()How far apart consecutive elements start, as a fraction of the animation: a wipe rather than a single pop.0(the default) starts everything at once, which is what a line wants: staggering the points of a line animates a wave through it. -
progress
protected final float progress()Overall animation progress in[0,1]; 1 means the data as it stands. -
elementProgress
protected final float elementProgress(int index, int count) Animation progress for elementindexofcount, withstaggerFraction()applied. Elements past the first start later and finish later, and every one of them reaches 1 by the timeprogress()does. -
seriesAlpha
protected final float seriesAlpha(int index) The alpha a series is currently drawn at, folding in its hide/show fade. -
drawnValue
protected final double drawnValue(int seriesIndex, int index) The value seriesseriesIndexis drawn at right now, animation included. -
pointFor
Builds aChartPointfor a datum, with the anchor the caller measured. -
tokens
The tokens for the step resolved on this chart; resolve once per pass, never in a field. -
measure
Measures a single line with the layout ruler (agrees with whatdrawTextdraws). -
ellipsize
textshortened with an ellipsis until it fitsmaxWidth, or""when not even the ellipsis fits. Category labels are application data: they are as long as they are, and a chart that lets them collide is unreadable.Shaped once and cut where
ShapedText.fitEnd(int, float)says, then re-shaped once or twice, the wayLabeldoes it. The obvious loop (drop a character, measure, repeat) made a label that overflows by forty characters cost forty shapings a paint, and a chart paints every frame of a value transition; worse, each candidate was a distinct string in the ruler's memo, so a few long labels evicted every other widget's text from it and everything on screen re-shaped each frame. -
onAttached
protected void onAttached()Description copied from class:WidgetCalled when this widget enters a scene (attached to the tree).Widget.scene()is the scene it just joined. Fires top-down, so a parent runs before its children. Default no-op.- Overrides:
onAttachedin classWidget
-
onMeasure
Description copied from class:WidgetReports the size this widget wants withinconstraints. Called once per layout pass, and the result is cached against the constraints and the resolved axes (size step, layout direction, locale), so it must be a pure function of them and of this widget's own state.Resolve the
ControlSizeand theLayoutDirectiononce each here and thread them down; never read either in a constructor. The locale needs no threading: it is in scope, andI18n.locale()answers it wherever text is resolved. -
onPaint
Description copied from class:WidgetWidget's own background/content, in local coordinates. -
onPaintOverlay
Description copied from class:WidgetPainted after children (scrollbars, focus rings…).- Overrides:
onPaintOverlayin classWidget
-
onMouseEvent
Description copied from class:WidgetMouse events (bubbling); callevent.consume()when handled.- Overrides:
onMouseEventin classWidget
-
stateFadeSeconds
protected final double stateFadeSeconds()How long a state fade lasts (hiding a series, popping a hovered mark), in seconds. Short, because it is feedback rather than data movement, and0wheneversetAnimationDuration(double)turned animation off, so "off" means all of it.
-