willdale / SwiftUICharts

A charts / plotting library for SwiftUI. Works on macOS, iOS, watchOS, and tvOS and has accessibility features built in.
MIT License
843 stars 105 forks source link

Different Stroke Styles in the same line #159

Closed kunalverma25 closed 2 years ago

kunalverma25 commented 2 years ago

While it is possible to have different solid colors in a single line using gradient stops (issue 157) It doesn't seem possible to have different stroke styles for a single line in a chart to create something like this - Screenshot 2022-01-10 at 6 13 54 AM

willdale commented 2 years ago

Hey @kunalverma25,

.stroke() gets applied to the whole line. I don't think there is a clean way to implement this in the library at the moment.

kunalverma25 commented 2 years ago

Closing the issue as stroke gets applied to the full line. Leaving a way to achieve the desired UI for anyone in need -

One way this can be achieved is by creating a multiline chart with both lines having the same data set. Then adding Gradient stops of required color (green and red in above image) and clear to the line styles of those line data sets. Line 1 (which will correspond to the top part) and Line 2 (bottom part)

Eg -

var topLineStyle = LineStyle(lineColour: ColourStyle(colour: .green),
                                                     lineType: .line,
                                                     strokeStyle: Stroke(lineWidth: 3))
var bottomLineStyle = LineStyle(lineColour: ColourStyle(colour: .red),
                                                        lineType: .line,
                                                        strokeStyle: Stroke(lineWidth: 3, dash: [5,5]))

topLineStyle.lineColour = ColourStyle(stops: [
    GradientStop(color: .clear, location: 0.0),
    GradientStop(color: .clear, location: YOUR_DIVIDING_LOCATION_VALUE(between 0 and 1),
    GradientStop(color: .green, location: YOUR_DIVIDING_LOCATION_VALUE),
    GradientStop(color: .green, location: 1)
], startPoint: .bottom, endPoint: .top)
bottomLineStyle.lineColour = ColourStyle(stops: [
    GradientStop(color: .red, location: 0.0),
    GradientStop(color: .red, location: YOUR_DIVIDING_LOCATION_VALUE),
    GradientStop(color: .clear, location: YOUR_DIVIDING_LOCATION_VALUE),
    GradientStop(color: .clear, location: 1)
], startPoint: .bottom, endPoint: .top)

Then your data sets needs to be setup with both line styles -

let dataSets = [LineDataSet(dataPoints: dataPoints,  
                            style: topLineStyle), 
                LineDataSet(dataPoints: dataPoints, 
                            style: bottomLineStyle)]
let dataSet = MultiLineDataSet(dataSets: dataSets)
return MultiLineChartData(dataSets: dataSet) // <- return/modify your data