Class CartesianChart

java.lang.Object
limn.scene.Widget
limn.components.chart.Chart
limn.components.chart.CartesianChart
Direct Known Subclasses:
BarChart, LineChart

public abstract class CartesianChart extends Chart
The half of a chart that has axes: a category axis with one slot per label and a value axis with a scale over the numbers. BarChart and LineChart share it; DonutChart does not, which is why this is its own class rather than part of Chart.

Both axes are automatic (see ChartAxis) and both can be pinned. The chart resolves the scale from the values the application set (never from the animated in-between), so an axis does not slide around while its bars grow into it.

Orientation is a property, not a class. setHorizontal(boolean) swaps which screen axis carries the values, and everything downstream (grid, labels, marks, hit-testing, the tooltip) runs through valuePosition(double) and bandStart(int), so the two orientations cannot drift apart.

Direction goes through the same two doors. A chart read right to left runs its value scale and its category sequence from the right edge of the plot, and the axis labels sit in a gutter on that side. Both mirrors live in valuePosition and bandStart, so a subclass placing a mark or hit-testing one gets the mirror for free and must not apply a second one. The vertical axis is not a reading axis and never moves.

  • Method Details

    • valueAxis

      public final ChartAxis valueAxis()
      The axis carrying the numbers: vertical unless setHorizontal(boolean).
    • categoryAxis

      public final ChartAxis categoryAxis()
      The axis carrying the labels: horizontal unless setHorizontal(boolean).
    • isStacked

      public final boolean isStacked()
      Whether series accumulate instead of standing beside each other.
    • setStacked

      public final CartesianChart setStacked(boolean value)
      Stacks the series that share a stack key on top of each other. Positive and negative values stack away from zero on their own sides, so a mixed series does not cancel itself out mid-column.
    • isHorizontal

      public final boolean isHorizontal()
      Whether the value axis runs left-to-right instead of bottom-to-top.
    • setHorizontal

      public final CartesianChart setHorizontal(boolean value)
      Turns the chart on its side: values run left-to-right and categories down the left edge. The layout long labels want: a vertical axis gives each one a whole row instead of a band the width of one bar.
    • plotX

      protected final float plotX()
      Left edge of the plot region, in the chart's local coordinates.
    • plotY

      protected final float plotY()
      Top edge of the plot region, in the chart's local coordinates.
    • plotWidth

      protected final float plotWidth()
      Width of the plot region.
    • plotHeight

      protected final float plotHeight()
      Height of the plot region.
    • scale

      protected final limn.components.chart.ChartAxis.Scale scale()
      The resolved value scale: the two ends drawn and the tick spacing between them.
    • valuePosition

      protected final float valuePosition(double value)
      Where value falls along the value axis, in local coordinates.

      Only the sideways branch is on the reading axis, and only it mirrors: the low end of the scale sits where reading starts, so it is the plot's right edge reading right to left. The upright branch is the vertical axis, which no direction moves.

    • bandSize

      protected final float bandSize()
      The width (or height, turned sideways) of one category slot.
    • bandStart

      protected final float bandStart(int index)
      The left edge (the top edge, turned sideways) of category index's band, in local coordinates.

      What mirrors is the coordinate, not the walk along the axis: the step from one category to the next stays index * bandSize() and only the point it is turned into is reflected, so a band is exactly one band wide at either end of the plot.

      What this returns is a band's box, not the point reading starts from. bandCenter(int), the hover band and every mark a subclass places compose from a left edge, so reflecting the point instead would move all three into the neighbouring band. The lines between bands are a different question, and bandBoundary(int) answers it.

    • bandCenter

      protected final float bandCenter(int index)
      The middle of category index along the category axis.

      A centre, and centres do not move: once bandStart(int) names the band's own left edge in either direction, this is already the middle of the right band.

    • animationBaseline

      protected final double animationBaseline()
      The value where the axis crosses the plot: zero when the scale contains it, the nearer end otherwise. Bars stand on it and areas fill down to it.
      Overrides:
      animationBaseline in class Chart
    • stackBase

      protected final double stackBase(int seriesIndex, int index)
      How much of its stack lies between the baseline and series seriesIndex at index, following the animation so a stack re-flows rather than jumping. 0 when the chart does not stack.
    • stackTotal

      protected final double stackTotal(int seriesIndex, int index)
      The sum of the stack seriesIndex belongs to at index, for shares.
    • stackKeys

      protected final List<String> stackKeys()
      The distinct stack keys of the visible series, in first-appearance order: one bar slot per key per category.

      Cached against Chart.dataGeneration() because it is walked once per bar per frame: rebuilt per call, a stacked chart allocated a list for every bar it drew.

    • paintMarks

      protected abstract void paintMarks(Canvas canvas)
      Paints the marks inside the plot region; grid and axes are already down.
    • pickSeries

      protected abstract int pickSeries(int category, float localX, float localY)
      Which series a pointer inside category is reporting: the mark it is on if any, and otherwise the nearest one, so a click in the whitespace of a column still names a datum. -1 when the category has nothing visible in it.
    • pointOf

      protected abstract ChartPoint pointOf(int seriesIndex, int category)
      The datum for one series at one category, anchored at that series' mark.
    • paintContent

      protected void paintContent(Canvas canvas, float x, float y, float w, float h)
      Description copied from class: Chart
      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.
      Specified by:
      paintContent in class Chart
    • pickAt

      protected ChartPoint pickAt(float localX, float localY)
      Description copied from class: Chart
      The datum under a point in the chart's local coordinates, or null when the pointer is not over the marks. Called for hover and for clicks, so it decides both.
      Specified by:
      pickAt in class Chart
    • tooltipRows

      protected List<ChartPoint> tooltipRows(ChartPoint picked)
      Description copied from class: Chart
      The rows a tooltip shows for picked. The default is Chart.TooltipMode.INDEX-aware: every visible series at the same index, or just the picked datum in Chart.TooltipMode.POINT.
      Overrides:
      tooltipRows in class Chart
    • categoryAt

      protected final int categoryAt(float localX, float localY)
      The category a local point falls in, or -1 outside the plot.

      The exact inverse of bandStart(int): it counts from the same end of the plot that category zero's band begins at, so the band the pointer names and the band painted under it are the same one. A mismatch here shows up as a tooltip naming the neighbouring bar and as nothing at all in a screenshot.