0

this is what i get when i try to change the color sorry can't post image here yet so i suggested to use link

I used RectangleMark from apple Charts Api here is my chart, my chartData has low, high, open, and close prices I want to have it to look like a normal candle stick chart, red when it is down, green when it is up using the open and close price value

I made a @State chartColor to have it changed with func to trigger it, but I get all of the chart red instead of a proper candle stick chart

Here is my code

import SwiftUI
import Charts
struct CoinChart: View {
    @ObservedObject var chartManager: ChartManager
    @State var chartColor: Color
    

func colorChange(){
    for content in chartManager.chartData.data {
        
        let openPrice = Double(content.open)
        let closePrice = Double(content.close)
        if closePrice! < openPrice! {
            chartColor = Color.red
        } else {
            chartColor = Color.green
        }
    }
}
var body: some View {
    
    VStack {
        
        Chart{
            ForEach(chartManager.chartData.data, id: \.self) { chartData in
                
                let date = chartManager.unixConverter(unixTime: Double(chartData.period))
                let dates = Date(timeIntervalSince1970: Double(chartData.period))
                let lowPrice = Double(chartData.low)
                let highPrice = Double(chartData.high)
                let openPrice = Double(chartData.open)
                let closePrice = Double(chartData.close)
                RectangleMark(x: .value("Time", date),
                              yStart: .value("Low Price", lowPrice!),
                              yEnd: .value("High Price", highPrice!), width: 1)
                .foregroundStyle(chartColor)
                
                RectangleMark(x: .value("Time", date),
                              yStart: .value("Open Price", openPrice!),
                              yEnd: .value("Close Price", closePrice!), width: 6)
                .foregroundStyle(chartColor)

            }
        }
        
        .chartYScale(domain: 18000...21000)
        .chartXAxis {
            AxisMarks(position: .bottom) { _ in
                AxisGridLine().foregroundStyle(.clear)
                AxisTick().foregroundStyle(.clear)
                AxisValueLabel()
                
            }
        }
        
        .frame(height: 300)
        
        Text(String(chartManager.chartData.data.count))
        
    }
    .task {
        await chartManager.loadChartData()
        colorChange()
    }
}
}

I called the func colorChange() in the task cuz if I call it in the chart it will give me a purple warning

Modifying state during view update, this will cause undefined behavior.

Any help will be appreciated everyone?

Thanks in advance

Sargis
  • 1,196
  • 1
  • 18
  • 31
Jono Then
  • 3
  • 6
  • Do yourself a favour and stop constantly doing this: `let lowPrice = Double(chartData.low)` etc... Make `chartData.low` etc... `Double` to start with. – workingdog support Ukraine Oct 24 '22 at 00:41
  • have you tried using this: `.foregroundStyle(closePrice! < openPrice! ? .red : .green)`, instead of your `colorChange()` thing. – workingdog support Ukraine Oct 24 '22 at 08:23
  • hey man, i am sorry if my code is messy, quite new to this, trying to figure my way out the whole chartdata.low etc are returned from api call, they r all in string value for some reason, and i dunno how to convert them to double other than the way i was doing it – Jono Then Oct 24 '22 at 08:46
  • hey @workingdogsupportUkraine it worked man, Jesus i can't believe how stupid i was again i thank you for your help – Jono Then Oct 24 '22 at 08:48
  • how do i mark your comment as an accepted answer? – Jono Then Oct 24 '22 at 08:48
  • glad it worked, don't worry about the accepted answer, thanks anyway. Why are your values String type? You read them as Doubles (from your previous post). If you really need to convert them to Doubles, and I really doubt you have to, then do it as you read them, or just after, then you are good to go with Doubles after that. – workingdog support Ukraine Oct 24 '22 at 13:20
  • hey, you still remember that haha yes, it was double, but the JSON was in a very strange kinda format, where I had to read the data in the array using indices, to make the chart I realized I have manipulate the range of the data, but I was not able to do so using the prev dataset, I found a new API that allows me to do that and better structured, but somehow the data values are in String type – Jono Then Oct 25 '22 at 08:53

0 Answers0