Skip to content

Draw LineChart entirely on Canvas, including indicators and labels#164

Open
brayellison wants to merge 2 commits intoehsannarmani:masterfrom
brayellison:line-chart-on-canvas
Open

Draw LineChart entirely on Canvas, including indicators and labels#164
brayellison wants to merge 2 commits intoehsannarmani:masterfrom
brayellison:line-chart-on-canvas

Conversation

@brayellison
Copy link
Copy Markdown

@brayellison brayellison commented Feb 26, 2026

The idea is that drawing the indicators and labels directly on the canvas opens up many additional features:

  • You can accurately place axis lines based on indicator values
  • Indicator values don't need to be evenly spaced and can be properly represented on the chart
    • May also open up the prospect of a log axis
  • The text at the indicator values can be properly centered
  • There's no longer a need to use composables + canvas to be able to express the LineChart, it's entirely self-contained
  • It opens up the possibility of the labels axis to be used for formats other than Strings (Number/DateTime/etc.) and have accurately placed (x, y) coordinates.

Before:
image

After:
image

I started out updating this for personal use, but I thought it might be helpful for the project overall.

One more thing that does need to be looked at, the rotation of the labels was removed. It shouldn't be difficult to add that back in within this framework though.

Let me know if there's anything else you'd like to see.

… canvas instead of delegating to composables

cleanup required, but it's working

general cleanup, remove unused, apply formatting

bugfix: coerce to inset bounds, check before `showPopup` unnecessary

remove draw grid in favor of calculated heights/widths of indicators/labels, add `drawTicks`, use ticks passed from `insetDrawScope` within `LineChartCanvas`. Added test cases to initial chart in `PhoneSample`

couple fixes

fix errors after removing dividerProperties
…djust inset calculation to avoid crash on screen orientation change

change `clipRect` to just on the paths, avoids clipping dots on the boundary, cleanup

refactor `Bounds` and `InsetPad` into utilities, add handling of label rotation

update `PhoneSample` with label rotation

fix imports
@brayellison
Copy link
Copy Markdown
Author

brayellison commented Feb 28, 2026

Added label rotation back, ended up experimenting with different clipping techniques and settled on just clipping the paths to the inset bounds and leaving the dots unclipped. Below is an example for my specific use case.

I'm plotting heart rate zones and steps per minute. For the heart rate zones, I am now able to plot the indicator values accurately. And for the steps per minute I'm able to limit indicator values to a reasonable range and ignore potential outliers in measurements.

line_chart_example

@brayellison
Copy link
Copy Markdown
Author

This solution may end up making #135 and #143 possible. I'm thinking I may branch off of this and try to work on drawing paths with (x, y) coordinates next.

@kritan10
Copy link
Copy Markdown

Any further updates on this?

Also would it be possible to extract x,y values and provide it as an argument (similar to the Slider with SliderState and onValueChange) to the LineChart composable. This way, we can use the values elsewhere and not just be limited to viewing it in the popup.

For example, in the steps per minute graph, I would be able to see the exact steps/minute value at minute 4 and display it in a Text composable.

@brayellison
Copy link
Copy Markdown
Author

brayellison commented Mar 30, 2026

For example, in the steps per minute graph, I would be able to see the exact steps/minute value at minute 4 and display it in a Text composable.

@kritan10 That would be interesting, I don't think it would be too difficult. I made another branch off this one that defines a space object to convert points to offsets, which you could inverse to get points from offsets.

Here's a link, but it's not the latest commit. I can push up the latest commit, it may need a little cleanup first. It's a significant overhaul, so I was waiting for this to get merged, then I was gonna open another PR.

Example from current iteration:

Screenshot_20260329-192435.png

@brayellison
Copy link
Copy Markdown
Author

@kritan10 commit pushed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants