Ahmad N.
Ahmad N.

Reputation: 53

Swiftui Charts Multiple Color LineMark

I’m using Swiftui Charts and I’m trying to achieve the same effect in the image taken from Apple Health app. What I really want to do is have part of a LineMark in the chart with one color and another part with a different color. The problem is that it picks up only the color of the last LineMark. The same thing also applies to the line style, it looks like I can only apply one style and color to the line.Apple Health app

Upvotes: 2

Views: 2449

Answers (1)

Jordan
Jordan

Reputation: 341

One way to achieve an effect like this is by using Gradient with stops:

Say you have your data type like this:

struct DataPoint: Identifiable {
    let id: UInt
    let y: Double

    static func mock(count: UInt) -> [DataPoint] {
        var mockData = [DataPoint]()
        for id in 0..<count {
            mockData.append(DataPoint(id: id, y: Double.random(in: 1...10)))
        }
        return mockData
    }
}

All you need to to is calculate the position (in per cent) of the color change. (Here mocked using constant called positionForNewColor)

Your ChartView can look like this

struct ChartView: View {
    var chartData: [DataPoint] = DataPoint.mock(count: 15)

    let positionForNewColor = 0.83

    var body: some View {
        Chart(chartData) { dataPoint in
            LineMark(
                x: .value("x", dataPoint.id),
                y: .value("y", dataPoint.y)
            )
            .lineStyle(.init(lineWidth: 3))
            .foregroundStyle(
                .linearGradient(
                    Gradient(
                        stops: [
                            .init(color: .purple, location: 0),
                            .init(color: .purple, location: positionForNewColor),
                            .init(color: .gray, location: positionForNewColor + 0.001),
                            .init(color: .gray, location: 1),
                    ]),
                    startPoint: .leading,
                    endPoint: .trailing)
            )
            .symbol(.circle)
            .symbolSize(150)
            .interpolationMethod(.catmullRom)
        }
        .frame(height: 200)
    }
}

This results in: A line chart where the left 83% is purple and the right side is grey.

Upvotes: 5

Related Questions