patrykandpatrick / vico

A light and extensible chart library for Android.
https://patrykandpatrick.com/vico/wiki
Apache License 2.0
2.15k stars 130 forks source link

Dashed lines / modifying line paint style #196

Closed TomBell-Trove closed 1 year ago

TomBell-Trove commented 1 year ago

Thanks for the neat lib. I'm investigating using this but have come across a problem, how to create a dashed line in a linegraph?

I see that LineSpec uses a paint object, but there's no setter for it. Furthermore it's final so I can't just make my own DashedLineSpec.

protected val linePaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
    style = Paint.Style.STROKE
    color = lineColor
    strokeCap = lineCap
}

public fun drawLine(context: DrawContext, path: Path): Unit = with(context) {
    linePaint.strokeWidth = lineThicknessDp.pixels
    canvas.drawPath(path, linePaint)
}

Is there a method for modifying this paint object or some other way of creating a dashed line I haven't noticed?

If not, could you please make linePaint open, or put it in the constructor? 😇

Gowsky commented 1 year ago

Hi @TomBell-Trove, Dashed lines are not supported yet, but we'll make sure to support them in the API. Thanks for your suggestion!

Gowsky commented 1 year ago

Unfortunately, it turns out that the dashed line support in LineSpec won’t be directly supported by the API. Due to the fact that the line Path object is constructed only for visible parts of the chart, there is a problem with dashes changing their position on a horizontal scroll. As of now, I can’t think of a reliable solution for this problem other than always constructing a whole path object. But this will hurt performance for large, and scrollable line charts. We want to avoid that.

With #205 the API of both LineChart and ColumnChart will be more open for extensions. Depending on your use case you may decide to construct the whole line path by overriding or replacing forEachPointWithinBoundsIndexed function in LineChart, so it does not check the visible bounds. The linePaint in LineSpec is already protected, and derived classes can edit its properties.

drachim-dev commented 3 months ago

Unfortunately, it turns out that the dashed line support in LineSpec won’t be directly supported by the API. Due to the fact that the line Path object is constructed only for visible parts of the chart, there is a problem with dashes changing their position on a horizontal scroll. As of now, I can’t think of a reliable solution for this problem other than always constructing a whole path object. But this will hurt performance for large, and scrollable line charts. We want to avoid that.

With #205 the API of both LineChart and ColumnChart will be more open for extensions. Depending on your use case you may decide to construct the whole line path by overriding or replacing forEachPointWithinBoundsIndexed function in LineChart, so it does not check the visible bounds. The linePaint in LineSpec is already protected, and derived classes can edit its properties.

@Gowsky Can you provide an example for a dashed line in the current alpha version or post a code snippet?

Gowsky commented 3 months ago

@drachim-dev, please see here and here. If you have any specific questions, let me know.

Also, we've determined a new way to add dashed lines to the library and we'll be implementing them soon. Please see #469.