Swift Charts

RSS for tag

Visualize data with highly customizable charts across all Apple platforms using the compositional syntax of SwifUI.

Posts under Swift Charts tag

195 Posts

Post

Replies

Boosts

Views

Activity

Chart - Last (right most) x axis label not being displayed
I have a swift program that displays a chart using Chart. The code includes an X Axis Scale parameter but for some reason the last value (right most) on the x axis does not display. It should display Aug 2023. In checking the array used for the x axis labels I find that the last value is Aug 2023. I do not know how to overcome this obstacle. Any assistance will be appreciated. Below is a picture of the bottom of the chart and the code. struct CustomChartView: View { let vm: SQLDataVM = SQLDataVM.shared let closingValues: [TradingDay] let fundName: String let numYears: Int let maxCloseStruct: TradingDay let maxClose: Double let minCloseStruct: TradingDay let minClose: Double let yIncrment: Double let yAxisValues: [Double] let minTimeStampStruct: TradingDay let minTimeStamp: Date var dateComponent = DateComponents() let maxTimeStampStruct: TradingDay let maxTimeStamp: Date var xAxisValues: [Date] = [] init (fundName: String, numYears: Int) { self.fundName = fundName self.numYears = numYears closingValues = self.vm.QueryDatabase(fundName: fundName, numYears: numYears) maxCloseStruct = self.closingValues.max(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.close < tradingDay2.close })! maxClose = maxCloseStruct.close minCloseStruct = closingValues.min(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.close < tradingDay2.close })! minClose = minCloseStruct.close yIncrment = (maxClose - minClose)/4 yAxisValues = [ minClose, minClose + (1 * yIncrment), minClose + (2 * yIncrment), minClose + (3 * yIncrment), maxClose ] minTimeStampStruct = closingValues.min(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.timeStamp < tradingDay2.timeStamp })! minTimeStamp = minTimeStampStruct.timeStamp maxTimeStampStruct = closingValues.max(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.timeStamp < tradingDay2.timeStamp })! maxTimeStamp = maxTimeStampStruct.timeStamp xAxisValues.append(minTimeStamp) for i in 1...11 { dateComponent.month = i let nextMonth = Calendar.current.date(byAdding: dateComponent, to: minTimeStamp) xAxisValues.append(nextMonth!) } xAxisValues.append(maxTimeStamp) print("\(xAxisValues[12])") // prints 2023-08-04 00:00:00 +0000 } // end init var body: some View { HStack(alignment: .center) { VStack(alignment: .center) { Chart(closingValues, id:\.id) { LineMark( x: .value("Date", $0.timeStamp, unit: .day), y: .value("Closing", $0.close) ) .foregroundStyle(.blue) } // end chart .frame(width: 1000, height: 700, alignment: .center) .chartXAxisLabel(position: .bottom, alignment: .center, spacing: 15) { Text("Date") .font(.custom("Arial", size: 20)) } .chartYAxisLabel(position: .leading, alignment: .center, spacing: 20) { Text("Closing Value") .font(.custom("Arial", size: 20)) } .chartXAxis { AxisMarks(values: xAxisValues) { value in if let date = value.as(Date.self) { AxisValueLabel(horizontalSpacing: -14, verticalSpacing: 10) { VStack(alignment: .leading) { Text(ChartMonthFormatter.string(from: date)) .font(.custom("Arial", size: 14)) Text(ChartYearFormatter.string(from: date)) .font(.custom("Arial", size: 14)) } // end v stack } // end axis label } // end if statement AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) .foregroundStyle(Color.black) AxisTick(centered: true, length: 0, stroke: .none) } } // end chart x axis .chartXScale(domain: [xAxisValues[0], xAxisValues[12]]) .chartYAxis { AxisMarks(position: .leading, values: yAxisValues) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) .foregroundStyle(Color.black) AxisTick(centered: true, length: 0, stroke: .none) AxisValueLabel(horizontalSpacing: 10) { if let yAxisValue = value.as(Double.self) { let stringValue = String(format: "$%.02f", yAxisValue) Text(stringValue) .font(.custom("Arial", size: 14)) } } } } .chartYScale(domain: [minClose, maxClose]) .chartPlotStyle { plotArea in plotArea.background(.white.opacity(0.9)) .border(.black, width: 1) } // end chart plot style } // end v stack .frame(width: 1200, height: 900, alignment: .center) } // end h stack } // end some view }
2
0
2.7k
Sep ’23
Swift Charts Animation setting X and Y domain doesn't works
I want the line grow without a canvas resize so I need to scale the canvas before the animation. If I apply both X and Y Scale modifiers to set the domain, animation doesn't work, if I comment either of both, yes... Any idea why and any workaround? import SwiftUI import Charts struct Entry: Identifiable { var id = UUID() var time: Double var value: Double } struct ContentView: View { @State var data: [Entry] = [ .init(time: 0, value: 0), .init(time: 1, value: 1)] var body: some View { VStack{ Button("+"){ data.append(.init(time: 2, value: 3)) } Chart(data){entry in LineMark(x: .value("time", entry.time), y: .value("value", entry.value)) } .chartXScale(domain: 0...3) .chartYScale(domain: 0...3) .padding() .animation(.easeIn(duration:3), value: data) } } }
0
0
948
Sep ’23
SwiftUI Chart Text Animation Glitch with AxisMarks and AxisLabels
I've encountered an animation glitch affecting the text for AxisMarks and AxisLabels in the SwiftUI Chart framework. Below are the sample project code and animated gif for reference: (I'm not being able to attach the gif for some reason. Here's my StackOverflow post with a the gift: https://stackoverflow.com/questions/77007744/swiftui-chart-text-animation-glitch-with-axismarks-and-axislabels) struct ContentView: View { @State var isDisplayingAge = true var body: some View { ChartView(data: ChartDataSample, isDisplayingAge: isDisplayingAge) .onTapGesture { withAnimation { isDisplayingAge.toggle() } } } } struct ChartData: Identifiable { let age: Int let presence: Int let grade: Int let id = UUID() } struct ChartView: View { let data: [ChartData] let isDisplayingAge: Bool let xAxis = [0, 50, 100] var body: some View { VStack { Chart { ForEach(data) { chartData in BarMark(x: .value("X Axis", isDisplayingAge ? chartData.age : chartData.presence), y: .value("Y Axis", chartData.grade)) } } .chartXAxis(content: { AxisMarks(position: .bottom, values: xAxis.map{$0}) { data in AxisValueLabel(String(xAxis[data.index]) + (isDisplayingAge ? " years" : " days")) } }) .chartXAxisLabel(content: { Text(isDisplayingAge ? "Data: age" : "Data: presence") }) } .padding(.horizontal, 13) } } As you can observe, when I tap the chart to trigger a content change with animation, the text for AxisMarks (e.g., x years / x days) and AxisLabels (e.g., Data: age / Data: presence) animates unusually. A portion of the text is temporarily replaced by an ellipsis ("...") during the animation. Interestingly, this issue occurs only in one direction of the animation. When transitioning from "year" to "day" or from "presence" to "age," the text simply gets replaced without any noticeable animation. Can anyone explain what's happening here? Ideally, I'd like the texts to either fade into each other or be replaced without any animation. Thank you.
1
0
1.4k
Aug ’23
show full week in charts even when days are empty
Hi, im building a swiftui chart for showing hours per day. it works fine. but I want to display a whole week even if there is no data on several days. it is based on core data. does anyone know how to modify x axis to show always the full week? thx Chris Chart { ForEach(zeiten, id: \.self.startdatum?.weekDay) { zeit in BarMark( x: .value("day", zeit.startdatum ?? Date(), unit: .day), yStart: .value("Low", zeit.startzeit?.timeDouble ?? 0), yEnd: .value("High", zeit.endzeit?.timeDouble ?? 0)) } .cornerRadius(8) .foregroundStyle(.userGreen) } .frame(width: geometry.size.width*0.75, height: 90) .padding() .chartYScale(domain: 0...24) .chartXAxis { AxisMarks(values: .stride(by: .day, count: 1)) { _ in AxisValueLabel(format: .dateTime.weekday(.narrow)) AxisGridLine() AxisTick() } }
1
0
2.4k
Aug ’23
Automatically LineMark scaling in Charts
How to scale LineMark to fill all chart automatically? Here is my sample: import SwiftUI import Charts struct EnergyView: View { var body: some View { VStack { Chart { ForEach(DailyEnergy.mockData) { dailyEnergy in LineMark(x: .value("Data", dailyEnergy.date), y: .value("Value", dailyEnergy.energy)) PointMark(x: .value("Data", dailyEnergy.date), y: .value("Value", dailyEnergy.energy)) .annotation(alignment: .center, spacing: 10) { Text("\(Int(dailyEnergy.energy))") .minimumScaleFactor(0.5) .scaledToFit() .frame(width: 40) } } .interpolationMethod(.monotone) } }.frame(height: 100) } } struct EnergyView_Previews: PreviewProvider { static var previews: some View { EnergyView() } } struct DailyEnergy: Identifiable { let id: UUID = .init() let date: Date let energy: Double } extension DailyEnergy { static var mockData: [Self] { [ .init(date: "2023-08-01".formattedDate, energy: 1376), .init(date: "2023-08-02".formattedDate, energy: 1576), .init(date: "2023-08-03".formattedDate, energy: 1875), .init(date: "2023-08-04".formattedDate, energy: 1676), .init(date: "2023-08-05".formattedDate, energy: 1475), .init(date: "2023-08-06".formattedDate, energy: 1574), .init(date: "2023-08-07".formattedDate, energy: 1674) ] } } and here is result what I have: and here is result what I'm expect: I want to build LineMark on full chart view, but how I can do this? I tried to use scalledToFill(), but it change all chart instead only LineMark, also I tried to use .chartYScale(domain: 1200...2800), but in this case I can't be sure that all chart line will be fitted to chart view including my PointMark. Maybe Charts has any function to do this?
0
0
770
Aug ’23
SwiftUI Charts AxisValueLabel disappears when using centered: true
Hi there, When using the AxisValueLabel in Swift Charts, the moment you add centered: true, the month or day on the right disappears. This has been a bug for over five months since I looked through other developer forums and they had the same issue. AxisValueLabel(format: .dateTime.weekday(), centered: true) leads to the following view: Now if we remove the centered: true, saturday will appear. It is probably a spacing issue, but since these are modifiers provided by Apple, it should do it correctly, right? If I am missing something and this is by desing, please enlighten me. Best Til
1
0
1.5k
Aug ’23
Swift Charts Slow Navigation
I'm experiencing a problem where my NavigationLink hangs when on the same view as a somewhat complicated chart. Additional Context: My Swift Chart has a fair number of data points (2000+). I'm also doing custom modification using the .chartYAxis modifier. .chartYAxis { AxisMarks(values: .stride(by: 1)) { value in            AxisGridLine()            AxisTick()            // In my app I also put a value label here, but that doesn't seem to be the thing in particular that slows this down.      } } When I do this modifier along with having a big set of data points, if I have a NavigationLink elsewhere on the same view, it hangs when I press the NavigationLink. Notably, if I remove this modifier, it doesn't hang. (By hang I mean it takes about 1s to navigate to the next view). Here's a slightly contrived example that mirrors my actual app, minus the generation of data points: import SwiftUI import Charts struct ContentView: View {     var body: some View {         NavigationStack {             NavigationLink(value: "NavigationKey") {                 Text("Link")             }             ChartView()             Text("Main View")                 .navigationDestination(for: String.self) { path in                     SomeView()                 }         }     } } struct ChartView: View {     var chartXY: [(x: Double, y: Double)] {         var entries: [(x: Double, y: Double)] = []         for i in 0..<2500             let y = Double.random(in: 0..<8000)             entries.append((x: Double(i), y: y))         }         return entries     }          var body: some View {         List {             Chart {                 ForEach(chartXY, id: \.x) {                     LineMark(x: .value("x", $0.x), y: .value("y", $0.y))                 }             }             .frame(minHeight: 100.0)             // Commenting out this block == no hang             .chartYAxis {                 AxisMarks(values: .stride(by: 1)) { value in                     AxisGridLine()                     AxisTick()                     // In my app I also put a value label here, but that doesn't seem to be the thing in particular that slows this down.                 }             }         }     } } struct SomeView: View {     var body: some View {         Text("hello")     } } Presumably, given commenting out the block solves the problem, SwiftUI is preparing some large amounts of AxisMarks/GridLines/AxisTicks for the view transition. Is there someway for me to indicate that it shouldn't do that to prevent this problem? Or is there some other reason this would be hanging?
9
6
4.6k
Jul ’23
How do I get the current visible data items in a chart with scrolling enabled via chartScrollableAxes
Does anyone know of to get the currently visible data items in chart (e.g. BarMarks) on iOS 17 when using chartScrollableAxes. From the WWDC23 video of session "Explore pie charts and interactivity in Swift Charts" at time 8:18 you see that the "Total sales" lists the visible time frame (e.g. May 4 - June 4, 2023) and a few seconds late when the chart scrolls the values do update.
0
0
1k
Jul ’23
Charts X and Y Axis content not appearing
When using charts framework to make a Bar Chart after creating my fake data and creating the chart in the contentView no x or y axis contents appeared I was following a tutorial and they appeared with him any one can help Bar Chart import SwiftUI import Charts struct Items : Identifiable { var id = UUID() let type : String let value : Double } struct ContentView: View { let items : [Items] = [ Items(type: "Medical", value: 10000), Items(type: "Engeneering", value: 5000), Items(type: "singing", value: 15000), Items(type: "pilot", value: 1000), Items(type: "athlete", value: 18000), ] ![]("https://developer.apple.com/forums/content/attachment/73dd58fb-2753-4d65-be30-ad4ae7ebb1be" "title=Screen Shot 2023-07-10 at 6.19.04 AM.png;width=854;height=1598") var body: some View { NavigationView{ ScrollView{ Chart(items){item in BarMark( x: .value("Job", item.type), y: .value("salary", item.value) ) .foregroundStyle(.brown) .cornerRadius(10) } .frame(height: 200) .padding() } .navigationTitle("Charts") } }
2
0
761
Jul ’23
Scrollable Chart with chartXSelection
I like to have a scrollable chart with chartXSelection. How can that be accomplished? As soon as I have .chartXSelection the chart doesn't really scroll any more. I'm looking for some sort of delayed chartXSelection gesture, where the chartXSelection kicks in after a short delay of 1-2 seconds. The Apple Heath App does support this very nicely.
0
0
1.3k
Jul ’23
Set initial position on scrollable bar chart?
I have a scrollable barmark chart that is introduced in iOS 17 but I have problem to set the initial horizontal scroll position. I want to use the ".chartScrollPosition(initialX:..." but initialX needs to be of type Plottable I can't understand how I can define that. Here is an example, I want it to scroll to the far right (newest days). I show seven days at a time. import SwiftUI import Charts struct ContentView: View { let stepDays: [StepDay] = [ StepDay(date: Calendar.current.date(byAdding: .day, value: -10, to: Date())!, steps: 12342), StepDay(date: Calendar.current.date(byAdding: .day, value: -9, to: Date())!, steps: 8345), StepDay(date: Calendar.current.date(byAdding: .day, value: -8, to: Date())!, steps: 7656), StepDay(date: Calendar.current.date(byAdding: .day, value: -7, to: Date())!, steps: 4564), StepDay(date: Calendar.current.date(byAdding: .day, value: -6, to: Date())!, steps: 2344), StepDay(date: Calendar.current.date(byAdding: .day, value: -5, to: Date())!, steps: 7654), StepDay(date: Calendar.current.date(byAdding: .day, value: -4, to: Date())!, steps: 4532), StepDay(date: Calendar.current.date(byAdding: .day, value: -3, to: Date())!, steps: 6788), StepDay(date: Calendar.current.date(byAdding: .day, value: -2, to: Date())!, steps: 4567), StepDay(date: Calendar.current.date(byAdding: .day, value: -1, to: Date())!, steps: 5678), StepDay(date: Date(), steps: 1234)] var body: some View { Chart { ForEach(stepDays, id: \.date) { stepDay in BarMark( x: .value("Day", stepDay.weekDay), y: .value("Steps", stepDay.steps) ) } } .chartScrollableAxes(.horizontal) .chartXVisibleDomain(length: 7) // .chartScrollPosition(initialX: <#T##Plottable#>) // I want to scroll to far right so that I can see the newest days, can I do that with chartScrollPosition(initialX:... ??? } } struct StepDay { var date: Date var weekDay: String var steps: Int init(date: Date, steps: Int) { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "d/M" self.date = date self.weekDay = dateFormatter.string(from: date) self.steps = steps } }
2
0
2.1k
Jun ’23
I need to create Swift Charts using Sensor data
I have created Swift Charts using Ready Made Data Like below static let last12Months = [ (month: date(year: 2022, month: 6), KW: 3952, dailyAverage: 127, dailyMin: 95, dailyMax: 345), (month: date(year: 2022, month: 7), KW: 8322, dailyAverage: 124, dailyMin: 55, dailyMax: 255), (month: date(year: 2022, month: 8), KW: 2952, dailyAverage: 245, dailyMin: 99, dailyMax: 673), (month: date(year: 2022, month: 9), KW: 3352, dailyAverage: 875, dailyMin: 92, dailyMax: 623), (month: date(year: 2022, month: 10), KW: 3252, dailyAverage: 257,dailyMin: 55, dailyMax: 675), (month: date(year: 2022, month: 11), KW: 3232, dailyAverage: 537,dailyMin: 65, dailyMax: 643), (month: date(year: 2022, month: 12), KW: 9871, dailyAverage: 253,dailyMin: 25, dailyMax: 987), (month: date(year: 2023, month: 1), KW: 8623, dailyAverage: 235, dailyMin: 96, dailyMax: 353), (month: date(year: 2023, month: 2), KW: 7612, dailyAverage: 276, dailyMin: 64, dailyMax: 765), (month: date(year: 2023, month: 3), KW: 2335, dailyAverage: 978, dailyMin: 36, dailyMax: 456), (month: date(year: 2023, month: 4), KW: 9087, dailyAverage: 667, dailyMin: 63, dailyMax: 675), (month: date(year: 2023, month: 5), KW: 2823, dailyAverage: 865, dailyMin: 100, dailyMax: 765), (month: date(year: 2023, month: 6), KW: 9762, dailyAverage: 544, dailyMin: 36, dailyMax: 999), ] `but now I want to create same charts with real world reading like Health App. For example aim taking the sensor value through bluetooth, I can show the reading from sensor to app but how can I store the data for months and show them in Charts Any Ideas where am I lagging`
0
0
759
Jun ’23
Weight/second live chart memory overload
Hi all, I'm trying to implement a dynamic chart to log weight over time for an espresso app. I've been struggling to find recourses to plot a continuously updating chart so, I'm currently using a timer to append new data to an array and then redraw the chart. Thats all working fine but, I'm getting 1GB< Memory usage after appending only 15 seconds worth of data at 10 datapoints/second. I would love to find a way to optimise this. Here is my main View Controller. There is some connect to scale stuff in there but, for testing I'm bypassing the scale data. All I'm doing is upon opening the view I'm: starting a counter, converting the counter to a min, sec ,millisec value, appending time information from my counter to the array, appending a random value from 1-10 as my mock weight data to the array, calling my chart view because it lives in a different file import UIKit import AcaiaSDK import SwiftUI import Charts var cList: [weight_time] = [] var timer: Timer! var count: Double! var timeInDouble: Double! var isCounting: Bool! var hideview: Bool = true class ChartVC: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { } override func viewDidAppear(_ animated: Bool) { timeInDouble = 0 count = 0 createTimer() print("Timer Started") isCounting = true } override func viewWillDisappear(_ animated: Bool) { if isCounting == true { timer.invalidate() print("Timer Stopped") isCounting == false } } func createTimer(){ cList.removeAll() timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(counter), userInfo: nil, repeats: true) } @objc func counter(){ count += 0.1 let minutes = Int(count) / 60 % 60 let seconds = Int(count) % 60 let mil = Int(count*10) % 10 //print(mil) let m_s = String(format:"%02i.%02i%01i", minutes, seconds,mil) timeInDouble = Double(m_s) //if mil == 1 { fillChart() // } print(timeInDouble!) } func fillChart(){ cList.append(weight_time(weight: Float(.random(in: 1...10)) , time: timeInDouble)) setupView() } // MARK: test Chart import func setupView(){ let controller = UIHostingController(rootView: chartvalues()) guard let chartView = controller.view else{ return } view.addSubview(chartView) controller.view.isHidden = false chartView.snp.makeConstraints{make in make.centerY.equalToSuperview() make.leading.equalToSuperview().offset(15) make.trailing.equalToSuperview().inset(15) make.height.equalTo(300) } } } import Charts import Foundation import AcaiaSDK import UIKit struct weight_time:Identifiable { let id = UUID() let weight: Float let time: Double } struct chartvalues: View{ let testList = [ weight_time( weight: 0.0, time: 0.5), weight_time(weight: 0.5, time: 1.0), weight_time(weight: 1.2, time: 1.5), weight_time(weight: 1.72, time: 2.0), weight_time(weight: 2.8, time: 2.5), weight_time(weight: 3.0, time: 3.0), weight_time(weight: 4.25, time: 3.5), weight_time(weight: 4.94, time: 4.0), weight_time(weight: 5.62, time: 4.5), weight_time(weight: 6.6, time: 5.0) ] var body: some View{ if cList != nil { Chart(cList){ weight_time in LineMark( x: .value("Time", weight_time.time), y: .value("Weight", weight_time.weight) ).foregroundStyle(.red) } } //Text(cList) } }```
0
0
505
Jun ’23
How to Handle Split Data in `Charts`?
I have a dataset I want to have split between past/historic data and future/predicted data. The values for the predicted data take the last value from pastData and apply a decay function to show how much of something is left. I have the data split into two arrays (sampleData_History and sampleData_Future); I have also attempted this with the data combined (sampleData) and tried a conditional in the .foregroundStyle property. Chart { ForEach(sampleData_History) { item in RuleMark(x: .value("Now", Date.now, unit: .hour)).foregroundStyle(.orange) LineMark( x: .value("time", item.date, unit: .hour), y: .value("mg", item.amount) ) .foregroundStyle(Color.blue) AreaMark( x: .value("time", item.date, unit: .hour), y: .value("mg", item.amount) ).foregroundStyle(Color.teal.opacity(0.2)) } ForEach(sampleData_Future) { item in LineMark( x: .value("time", item.date, unit: .hour), y: .value("mg", item.amount) ) .foregroundStyle(Color.red) AreaMark( x: .value("time", item.date, unit: .hour), y: .value("mg", item.amount) ).foregroundStyle(Color.red.opacity(0.2)) } } The above code yields the screenshot below. In the ideal case, I'd like to have everything AFTER the RuleMark line be a different color. Am I missing something? Where might I look to figure this out? EDIT: I have also tried separating them into series to no avail
5
0
2.3k
Jun ’23
How do I animate a Swift line mark chart
I have a view that displays a chart based on an array. Each element in the array is all of the attributes associated with a core data entity. The data is properly displayed. I would like to animate the rendering of the charts data but cannot seem to figure out how to do it. If someone could point me in the right direction it would be appreciated. Below is the code. struct ClosingValuesChart: View { @State private var selectedDate: Date? = nil @State private var selectedClose: Float? = nil @State private var xAxisLabels: [Date] = [] var closingValues: [TradingDayClose] = [] var heading: String = "" init(fundName: String, numYears: Int, closingValues: [TradingDayClose]) { self.heading = fundName + String(" - \(numYears) Year") self.closingValues = closingValues } var body: some View { GroupBox (heading) { let xMin = closingValues.first?.timeStamp let xMax = closingValues.last?.timeStamp let yMin = closingValues.map { $0.close }.min()! let yMax = closingValues.map { $0.close }.max()! let xAxisLabels: [Date] = GetXAxisLabels(xMin: xMin!, xMax: xMax!) var yAxisLabels: [Float] { stride(from: yMin, to: yMax + ((yMax - yMin)/7), by: (yMax - yMin) / 7).map { $0 } } Chart { ForEach(closingValues) { value in LineMark( x: .value("Time", value.timeStamp!), y: .value("Closing Value", value.close) ) .foregroundStyle(Color.blue) .lineStyle(StrokeStyle(lineWidth: 1.25)) } } .chartXScale(domain: xMin!...xMax!) .chartXAxisLabel(position: .bottom, alignment: .center, spacing: 25) { Text("Date") .textFormatting(fontSize: 14) } .chartXAxis { AxisMarks(position: .bottom, values: xAxisLabels) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) AxisValueLabel(anchor: .top) { if value.as(Date.self) != nil { Text("") } } } } .chartYScale(domain: yMin...yMax) .chartYAxisLabel(position: .leading, alignment: .center, spacing: 25) { Text("Closing Value") .font(Font.custom("Arial", size: 14)) .foregroundColor(.black) } .chartYAxis { AxisMarks(position: .leading, values: yAxisLabels) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) AxisValueLabel() { if let labelValue = value.as(Double.self) { Text(String(format: "$ %.2f", labelValue)) .textFormatting(fontSize: 12) } } } } .chartOverlay { proxy in GeometryReader { geometry in ChartOverlayRectangle(selectedDate: $selectedDate, selectedClose: $selectedClose, proxy: proxy, geometry: geometry, xMin: xMin!, xMax: xMax!, closingValues: closingValues) } } .overlay { XAxisDates(dateLabels: xAxisLabels) } .overlay { DateAndClosingValue(selectedDate: selectedDate ?? Date(), selectedClose: selectedClose ?? 0.0) } } .groupBoxStyle(ChartGroupBoxStyle()) } }
4
0
3.1k
Jun ’23
Swift Charts in ObjC project using bridging headers?
Is it possible to use Swift Charts in my ObjC project using bridging headers? The documentation names its Swift Charts but its seems they can only be used in SwiftUI projects.
Replies
2
Boosts
0
Views
859
Activity
Sep ’23
Swift Charts Styling
How to apply Swift Charts, for instance, barmark, without x and y axes and labels?
Replies
0
Boosts
0
Views
611
Activity
Sep ’23
Chart - Last (right most) x axis label not being displayed
I have a swift program that displays a chart using Chart. The code includes an X Axis Scale parameter but for some reason the last value (right most) on the x axis does not display. It should display Aug 2023. In checking the array used for the x axis labels I find that the last value is Aug 2023. I do not know how to overcome this obstacle. Any assistance will be appreciated. Below is a picture of the bottom of the chart and the code. struct CustomChartView: View { let vm: SQLDataVM = SQLDataVM.shared let closingValues: [TradingDay] let fundName: String let numYears: Int let maxCloseStruct: TradingDay let maxClose: Double let minCloseStruct: TradingDay let minClose: Double let yIncrment: Double let yAxisValues: [Double] let minTimeStampStruct: TradingDay let minTimeStamp: Date var dateComponent = DateComponents() let maxTimeStampStruct: TradingDay let maxTimeStamp: Date var xAxisValues: [Date] = [] init (fundName: String, numYears: Int) { self.fundName = fundName self.numYears = numYears closingValues = self.vm.QueryDatabase(fundName: fundName, numYears: numYears) maxCloseStruct = self.closingValues.max(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.close < tradingDay2.close })! maxClose = maxCloseStruct.close minCloseStruct = closingValues.min(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.close < tradingDay2.close })! minClose = minCloseStruct.close yIncrment = (maxClose - minClose)/4 yAxisValues = [ minClose, minClose + (1 * yIncrment), minClose + (2 * yIncrment), minClose + (3 * yIncrment), maxClose ] minTimeStampStruct = closingValues.min(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.timeStamp < tradingDay2.timeStamp })! minTimeStamp = minTimeStampStruct.timeStamp maxTimeStampStruct = closingValues.max(by: { (tradingDay1, tradingDay2) -> Bool in return tradingDay1.timeStamp < tradingDay2.timeStamp })! maxTimeStamp = maxTimeStampStruct.timeStamp xAxisValues.append(minTimeStamp) for i in 1...11 { dateComponent.month = i let nextMonth = Calendar.current.date(byAdding: dateComponent, to: minTimeStamp) xAxisValues.append(nextMonth!) } xAxisValues.append(maxTimeStamp) print("\(xAxisValues[12])") // prints 2023-08-04 00:00:00 +0000 } // end init var body: some View { HStack(alignment: .center) { VStack(alignment: .center) { Chart(closingValues, id:\.id) { LineMark( x: .value("Date", $0.timeStamp, unit: .day), y: .value("Closing", $0.close) ) .foregroundStyle(.blue) } // end chart .frame(width: 1000, height: 700, alignment: .center) .chartXAxisLabel(position: .bottom, alignment: .center, spacing: 15) { Text("Date") .font(.custom("Arial", size: 20)) } .chartYAxisLabel(position: .leading, alignment: .center, spacing: 20) { Text("Closing Value") .font(.custom("Arial", size: 20)) } .chartXAxis { AxisMarks(values: xAxisValues) { value in if let date = value.as(Date.self) { AxisValueLabel(horizontalSpacing: -14, verticalSpacing: 10) { VStack(alignment: .leading) { Text(ChartMonthFormatter.string(from: date)) .font(.custom("Arial", size: 14)) Text(ChartYearFormatter.string(from: date)) .font(.custom("Arial", size: 14)) } // end v stack } // end axis label } // end if statement AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) .foregroundStyle(Color.black) AxisTick(centered: true, length: 0, stroke: .none) } } // end chart x axis .chartXScale(domain: [xAxisValues[0], xAxisValues[12]]) .chartYAxis { AxisMarks(position: .leading, values: yAxisValues) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) .foregroundStyle(Color.black) AxisTick(centered: true, length: 0, stroke: .none) AxisValueLabel(horizontalSpacing: 10) { if let yAxisValue = value.as(Double.self) { let stringValue = String(format: "$%.02f", yAxisValue) Text(stringValue) .font(.custom("Arial", size: 14)) } } } } .chartYScale(domain: [minClose, maxClose]) .chartPlotStyle { plotArea in plotArea.background(.white.opacity(0.9)) .border(.black, width: 1) } // end chart plot style } // end v stack .frame(width: 1200, height: 900, alignment: .center) } // end h stack } // end some view }
Replies
2
Boosts
0
Views
2.7k
Activity
Sep ’23
Swift Charts Animation setting X and Y domain doesn't works
I want the line grow without a canvas resize so I need to scale the canvas before the animation. If I apply both X and Y Scale modifiers to set the domain, animation doesn't work, if I comment either of both, yes... Any idea why and any workaround? import SwiftUI import Charts struct Entry: Identifiable { var id = UUID() var time: Double var value: Double } struct ContentView: View { @State var data: [Entry] = [ .init(time: 0, value: 0), .init(time: 1, value: 1)] var body: some View { VStack{ Button("+"){ data.append(.init(time: 2, value: 3)) } Chart(data){entry in LineMark(x: .value("time", entry.time), y: .value("value", entry.value)) } .chartXScale(domain: 0...3) .chartYScale(domain: 0...3) .padding() .animation(.easeIn(duration:3), value: data) } } }
Replies
0
Boosts
0
Views
948
Activity
Sep ’23
which one do i choose between FMDB and core Data in SwiftUI ?
i need to make app that make Database of received Serial data after receiving data , i need to show data using chart. Serial data traffic is not high, and is not happen frequently... and can i use FMDB at SwiftUI ?
Replies
1
Boosts
0
Views
809
Activity
Sep ’23
SwiftUI Chart Text Animation Glitch with AxisMarks and AxisLabels
I've encountered an animation glitch affecting the text for AxisMarks and AxisLabels in the SwiftUI Chart framework. Below are the sample project code and animated gif for reference: (I'm not being able to attach the gif for some reason. Here's my StackOverflow post with a the gift: https://stackoverflow.com/questions/77007744/swiftui-chart-text-animation-glitch-with-axismarks-and-axislabels) struct ContentView: View { @State var isDisplayingAge = true var body: some View { ChartView(data: ChartDataSample, isDisplayingAge: isDisplayingAge) .onTapGesture { withAnimation { isDisplayingAge.toggle() } } } } struct ChartData: Identifiable { let age: Int let presence: Int let grade: Int let id = UUID() } struct ChartView: View { let data: [ChartData] let isDisplayingAge: Bool let xAxis = [0, 50, 100] var body: some View { VStack { Chart { ForEach(data) { chartData in BarMark(x: .value("X Axis", isDisplayingAge ? chartData.age : chartData.presence), y: .value("Y Axis", chartData.grade)) } } .chartXAxis(content: { AxisMarks(position: .bottom, values: xAxis.map{$0}) { data in AxisValueLabel(String(xAxis[data.index]) + (isDisplayingAge ? " years" : " days")) } }) .chartXAxisLabel(content: { Text(isDisplayingAge ? "Data: age" : "Data: presence") }) } .padding(.horizontal, 13) } } As you can observe, when I tap the chart to trigger a content change with animation, the text for AxisMarks (e.g., x years / x days) and AxisLabels (e.g., Data: age / Data: presence) animates unusually. A portion of the text is temporarily replaced by an ellipsis ("...") during the animation. Interestingly, this issue occurs only in one direction of the animation. When transitioning from "year" to "day" or from "presence" to "age," the text simply gets replaced without any noticeable animation. Can anyone explain what's happening here? Ideally, I'd like the texts to either fade into each other or be replaced without any animation. Thank you.
Replies
1
Boosts
0
Views
1.4k
Activity
Aug ’23
show full week in charts even when days are empty
Hi, im building a swiftui chart for showing hours per day. it works fine. but I want to display a whole week even if there is no data on several days. it is based on core data. does anyone know how to modify x axis to show always the full week? thx Chris Chart { ForEach(zeiten, id: \.self.startdatum?.weekDay) { zeit in BarMark( x: .value("day", zeit.startdatum ?? Date(), unit: .day), yStart: .value("Low", zeit.startzeit?.timeDouble ?? 0), yEnd: .value("High", zeit.endzeit?.timeDouble ?? 0)) } .cornerRadius(8) .foregroundStyle(.userGreen) } .frame(width: geometry.size.width*0.75, height: 90) .padding() .chartYScale(domain: 0...24) .chartXAxis { AxisMarks(values: .stride(by: .day, count: 1)) { _ in AxisValueLabel(format: .dateTime.weekday(.narrow)) AxisGridLine() AxisTick() } }
Replies
1
Boosts
0
Views
2.4k
Activity
Aug ’23
Automatically LineMark scaling in Charts
How to scale LineMark to fill all chart automatically? Here is my sample: import SwiftUI import Charts struct EnergyView: View { var body: some View { VStack { Chart { ForEach(DailyEnergy.mockData) { dailyEnergy in LineMark(x: .value("Data", dailyEnergy.date), y: .value("Value", dailyEnergy.energy)) PointMark(x: .value("Data", dailyEnergy.date), y: .value("Value", dailyEnergy.energy)) .annotation(alignment: .center, spacing: 10) { Text("\(Int(dailyEnergy.energy))") .minimumScaleFactor(0.5) .scaledToFit() .frame(width: 40) } } .interpolationMethod(.monotone) } }.frame(height: 100) } } struct EnergyView_Previews: PreviewProvider { static var previews: some View { EnergyView() } } struct DailyEnergy: Identifiable { let id: UUID = .init() let date: Date let energy: Double } extension DailyEnergy { static var mockData: [Self] { [ .init(date: "2023-08-01".formattedDate, energy: 1376), .init(date: "2023-08-02".formattedDate, energy: 1576), .init(date: "2023-08-03".formattedDate, energy: 1875), .init(date: "2023-08-04".formattedDate, energy: 1676), .init(date: "2023-08-05".formattedDate, energy: 1475), .init(date: "2023-08-06".formattedDate, energy: 1574), .init(date: "2023-08-07".formattedDate, energy: 1674) ] } } and here is result what I have: and here is result what I'm expect: I want to build LineMark on full chart view, but how I can do this? I tried to use scalledToFill(), but it change all chart instead only LineMark, also I tried to use .chartYScale(domain: 1200...2800), but in this case I can't be sure that all chart line will be fitted to chart view including my PointMark. Maybe Charts has any function to do this?
Replies
0
Boosts
0
Views
770
Activity
Aug ’23
SwiftUI Charts AxisValueLabel disappears when using centered: true
Hi there, When using the AxisValueLabel in Swift Charts, the moment you add centered: true, the month or day on the right disappears. This has been a bug for over five months since I looked through other developer forums and they had the same issue. AxisValueLabel(format: .dateTime.weekday(), centered: true) leads to the following view: Now if we remove the centered: true, saturday will appear. It is probably a spacing issue, but since these are modifiers provided by Apple, it should do it correctly, right? If I am missing something and this is by desing, please enlighten me. Best Til
Replies
1
Boosts
0
Views
1.5k
Activity
Aug ’23
Swift Charts y-axis scale changes when RuleMark annotation is displayed
In a Swift Chart that listens for drag gestures in order to display a RuleMark with an annotation, the y-axis scale changes while dragging which causes the entire chart to jump. I have a small code example that demonstrates this at https://github.com/mvolkmann/ChartJump. See the two screenshots there.
Replies
4
Boosts
0
Views
3.2k
Activity
Jul ’23
Swift Charts Slow Navigation
I'm experiencing a problem where my NavigationLink hangs when on the same view as a somewhat complicated chart. Additional Context: My Swift Chart has a fair number of data points (2000+). I'm also doing custom modification using the .chartYAxis modifier. .chartYAxis { AxisMarks(values: .stride(by: 1)) { value in            AxisGridLine()            AxisTick()            // In my app I also put a value label here, but that doesn't seem to be the thing in particular that slows this down.      } } When I do this modifier along with having a big set of data points, if I have a NavigationLink elsewhere on the same view, it hangs when I press the NavigationLink. Notably, if I remove this modifier, it doesn't hang. (By hang I mean it takes about 1s to navigate to the next view). Here's a slightly contrived example that mirrors my actual app, minus the generation of data points: import SwiftUI import Charts struct ContentView: View {     var body: some View {         NavigationStack {             NavigationLink(value: "NavigationKey") {                 Text("Link")             }             ChartView()             Text("Main View")                 .navigationDestination(for: String.self) { path in                     SomeView()                 }         }     } } struct ChartView: View {     var chartXY: [(x: Double, y: Double)] {         var entries: [(x: Double, y: Double)] = []         for i in 0..<2500             let y = Double.random(in: 0..<8000)             entries.append((x: Double(i), y: y))         }         return entries     }          var body: some View {         List {             Chart {                 ForEach(chartXY, id: \.x) {                     LineMark(x: .value("x", $0.x), y: .value("y", $0.y))                 }             }             .frame(minHeight: 100.0)             // Commenting out this block == no hang             .chartYAxis {                 AxisMarks(values: .stride(by: 1)) { value in                     AxisGridLine()                     AxisTick()                     // In my app I also put a value label here, but that doesn't seem to be the thing in particular that slows this down.                 }             }         }     } } struct SomeView: View {     var body: some View {         Text("hello")     } } Presumably, given commenting out the block solves the problem, SwiftUI is preparing some large amounts of AxisMarks/GridLines/AxisTicks for the view transition. Is there someway for me to indicate that it shouldn't do that to prevent this problem? Or is there some other reason this would be hanging?
Replies
9
Boosts
6
Views
4.6k
Activity
Jul ’23
How do I get the current visible data items in a chart with scrolling enabled via chartScrollableAxes
Does anyone know of to get the currently visible data items in chart (e.g. BarMarks) on iOS 17 when using chartScrollableAxes. From the WWDC23 video of session "Explore pie charts and interactivity in Swift Charts" at time 8:18 you see that the "Total sales" lists the visible time frame (e.g. May 4 - June 4, 2023) and a few seconds late when the chart scrolls the values do update.
Replies
0
Boosts
0
Views
1k
Activity
Jul ’23
Charts X and Y Axis content not appearing
When using charts framework to make a Bar Chart after creating my fake data and creating the chart in the contentView no x or y axis contents appeared I was following a tutorial and they appeared with him any one can help Bar Chart import SwiftUI import Charts struct Items : Identifiable { var id = UUID() let type : String let value : Double } struct ContentView: View { let items : [Items] = [ Items(type: "Medical", value: 10000), Items(type: "Engeneering", value: 5000), Items(type: "singing", value: 15000), Items(type: "pilot", value: 1000), Items(type: "athlete", value: 18000), ] ![]("https://developer.apple.com/forums/content/attachment/73dd58fb-2753-4d65-be30-ad4ae7ebb1be" "title=Screen Shot 2023-07-10 at 6.19.04 AM.png;width=854;height=1598") var body: some View { NavigationView{ ScrollView{ Chart(items){item in BarMark( x: .value("Job", item.type), y: .value("salary", item.value) ) .foregroundStyle(.brown) .cornerRadius(10) } .frame(height: 200) .padding() } .navigationTitle("Charts") } }
Replies
2
Boosts
0
Views
761
Activity
Jul ’23
Scrollable Chart with chartXSelection
I like to have a scrollable chart with chartXSelection. How can that be accomplished? As soon as I have .chartXSelection the chart doesn't really scroll any more. I'm looking for some sort of delayed chartXSelection gesture, where the chartXSelection kicks in after a short delay of 1-2 seconds. The Apple Heath App does support this very nicely.
Replies
0
Boosts
0
Views
1.3k
Activity
Jul ’23
Set initial position on scrollable bar chart?
I have a scrollable barmark chart that is introduced in iOS 17 but I have problem to set the initial horizontal scroll position. I want to use the ".chartScrollPosition(initialX:..." but initialX needs to be of type Plottable I can't understand how I can define that. Here is an example, I want it to scroll to the far right (newest days). I show seven days at a time. import SwiftUI import Charts struct ContentView: View { let stepDays: [StepDay] = [ StepDay(date: Calendar.current.date(byAdding: .day, value: -10, to: Date())!, steps: 12342), StepDay(date: Calendar.current.date(byAdding: .day, value: -9, to: Date())!, steps: 8345), StepDay(date: Calendar.current.date(byAdding: .day, value: -8, to: Date())!, steps: 7656), StepDay(date: Calendar.current.date(byAdding: .day, value: -7, to: Date())!, steps: 4564), StepDay(date: Calendar.current.date(byAdding: .day, value: -6, to: Date())!, steps: 2344), StepDay(date: Calendar.current.date(byAdding: .day, value: -5, to: Date())!, steps: 7654), StepDay(date: Calendar.current.date(byAdding: .day, value: -4, to: Date())!, steps: 4532), StepDay(date: Calendar.current.date(byAdding: .day, value: -3, to: Date())!, steps: 6788), StepDay(date: Calendar.current.date(byAdding: .day, value: -2, to: Date())!, steps: 4567), StepDay(date: Calendar.current.date(byAdding: .day, value: -1, to: Date())!, steps: 5678), StepDay(date: Date(), steps: 1234)] var body: some View { Chart { ForEach(stepDays, id: \.date) { stepDay in BarMark( x: .value("Day", stepDay.weekDay), y: .value("Steps", stepDay.steps) ) } } .chartScrollableAxes(.horizontal) .chartXVisibleDomain(length: 7) // .chartScrollPosition(initialX: <#T##Plottable#>) // I want to scroll to far right so that I can see the newest days, can I do that with chartScrollPosition(initialX:... ??? } } struct StepDay { var date: Date var weekDay: String var steps: Int init(date: Date, steps: Int) { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "d/M" self.date = date self.weekDay = dateFormatter.string(from: date) self.steps = steps } }
Replies
2
Boosts
0
Views
2.1k
Activity
Jun ’23
I need to create Swift Charts using Sensor data
I have created Swift Charts using Ready Made Data Like below static let last12Months = [ (month: date(year: 2022, month: 6), KW: 3952, dailyAverage: 127, dailyMin: 95, dailyMax: 345), (month: date(year: 2022, month: 7), KW: 8322, dailyAverage: 124, dailyMin: 55, dailyMax: 255), (month: date(year: 2022, month: 8), KW: 2952, dailyAverage: 245, dailyMin: 99, dailyMax: 673), (month: date(year: 2022, month: 9), KW: 3352, dailyAverage: 875, dailyMin: 92, dailyMax: 623), (month: date(year: 2022, month: 10), KW: 3252, dailyAverage: 257,dailyMin: 55, dailyMax: 675), (month: date(year: 2022, month: 11), KW: 3232, dailyAverage: 537,dailyMin: 65, dailyMax: 643), (month: date(year: 2022, month: 12), KW: 9871, dailyAverage: 253,dailyMin: 25, dailyMax: 987), (month: date(year: 2023, month: 1), KW: 8623, dailyAverage: 235, dailyMin: 96, dailyMax: 353), (month: date(year: 2023, month: 2), KW: 7612, dailyAverage: 276, dailyMin: 64, dailyMax: 765), (month: date(year: 2023, month: 3), KW: 2335, dailyAverage: 978, dailyMin: 36, dailyMax: 456), (month: date(year: 2023, month: 4), KW: 9087, dailyAverage: 667, dailyMin: 63, dailyMax: 675), (month: date(year: 2023, month: 5), KW: 2823, dailyAverage: 865, dailyMin: 100, dailyMax: 765), (month: date(year: 2023, month: 6), KW: 9762, dailyAverage: 544, dailyMin: 36, dailyMax: 999), ] `but now I want to create same charts with real world reading like Health App. For example aim taking the sensor value through bluetooth, I can show the reading from sensor to app but how can I store the data for months and show them in Charts Any Ideas where am I lagging`
Replies
0
Boosts
0
Views
759
Activity
Jun ’23
Weight/second live chart memory overload
Hi all, I'm trying to implement a dynamic chart to log weight over time for an espresso app. I've been struggling to find recourses to plot a continuously updating chart so, I'm currently using a timer to append new data to an array and then redraw the chart. Thats all working fine but, I'm getting 1GB< Memory usage after appending only 15 seconds worth of data at 10 datapoints/second. I would love to find a way to optimise this. Here is my main View Controller. There is some connect to scale stuff in there but, for testing I'm bypassing the scale data. All I'm doing is upon opening the view I'm: starting a counter, converting the counter to a min, sec ,millisec value, appending time information from my counter to the array, appending a random value from 1-10 as my mock weight data to the array, calling my chart view because it lives in a different file import UIKit import AcaiaSDK import SwiftUI import Charts var cList: [weight_time] = [] var timer: Timer! var count: Double! var timeInDouble: Double! var isCounting: Bool! var hideview: Bool = true class ChartVC: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { } override func viewDidAppear(_ animated: Bool) { timeInDouble = 0 count = 0 createTimer() print("Timer Started") isCounting = true } override func viewWillDisappear(_ animated: Bool) { if isCounting == true { timer.invalidate() print("Timer Stopped") isCounting == false } } func createTimer(){ cList.removeAll() timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(counter), userInfo: nil, repeats: true) } @objc func counter(){ count += 0.1 let minutes = Int(count) / 60 % 60 let seconds = Int(count) % 60 let mil = Int(count*10) % 10 //print(mil) let m_s = String(format:"%02i.%02i%01i", minutes, seconds,mil) timeInDouble = Double(m_s) //if mil == 1 { fillChart() // } print(timeInDouble!) } func fillChart(){ cList.append(weight_time(weight: Float(.random(in: 1...10)) , time: timeInDouble)) setupView() } // MARK: test Chart import func setupView(){ let controller = UIHostingController(rootView: chartvalues()) guard let chartView = controller.view else{ return } view.addSubview(chartView) controller.view.isHidden = false chartView.snp.makeConstraints{make in make.centerY.equalToSuperview() make.leading.equalToSuperview().offset(15) make.trailing.equalToSuperview().inset(15) make.height.equalTo(300) } } } import Charts import Foundation import AcaiaSDK import UIKit struct weight_time:Identifiable { let id = UUID() let weight: Float let time: Double } struct chartvalues: View{ let testList = [ weight_time( weight: 0.0, time: 0.5), weight_time(weight: 0.5, time: 1.0), weight_time(weight: 1.2, time: 1.5), weight_time(weight: 1.72, time: 2.0), weight_time(weight: 2.8, time: 2.5), weight_time(weight: 3.0, time: 3.0), weight_time(weight: 4.25, time: 3.5), weight_time(weight: 4.94, time: 4.0), weight_time(weight: 5.62, time: 4.5), weight_time(weight: 6.6, time: 5.0) ] var body: some View{ if cList != nil { Chart(cList){ weight_time in LineMark( x: .value("Time", weight_time.time), y: .value("Weight", weight_time.weight) ).foregroundStyle(.red) } } //Text(cList) } }```
Replies
0
Boosts
0
Views
505
Activity
Jun ’23
How to Handle Split Data in `Charts`?
I have a dataset I want to have split between past/historic data and future/predicted data. The values for the predicted data take the last value from pastData and apply a decay function to show how much of something is left. I have the data split into two arrays (sampleData_History and sampleData_Future); I have also attempted this with the data combined (sampleData) and tried a conditional in the .foregroundStyle property. Chart { ForEach(sampleData_History) { item in RuleMark(x: .value("Now", Date.now, unit: .hour)).foregroundStyle(.orange) LineMark( x: .value("time", item.date, unit: .hour), y: .value("mg", item.amount) ) .foregroundStyle(Color.blue) AreaMark( x: .value("time", item.date, unit: .hour), y: .value("mg", item.amount) ).foregroundStyle(Color.teal.opacity(0.2)) } ForEach(sampleData_Future) { item in LineMark( x: .value("time", item.date, unit: .hour), y: .value("mg", item.amount) ) .foregroundStyle(Color.red) AreaMark( x: .value("time", item.date, unit: .hour), y: .value("mg", item.amount) ).foregroundStyle(Color.red.opacity(0.2)) } } The above code yields the screenshot below. In the ideal case, I'd like to have everything AFTER the RuleMark line be a different color. Am I missing something? Where might I look to figure this out? EDIT: I have also tried separating them into series to no avail
Replies
5
Boosts
0
Views
2.3k
Activity
Jun ’23
How do I animate a Swift line mark chart
I have a view that displays a chart based on an array. Each element in the array is all of the attributes associated with a core data entity. The data is properly displayed. I would like to animate the rendering of the charts data but cannot seem to figure out how to do it. If someone could point me in the right direction it would be appreciated. Below is the code. struct ClosingValuesChart: View { @State private var selectedDate: Date? = nil @State private var selectedClose: Float? = nil @State private var xAxisLabels: [Date] = [] var closingValues: [TradingDayClose] = [] var heading: String = "" init(fundName: String, numYears: Int, closingValues: [TradingDayClose]) { self.heading = fundName + String(" - \(numYears) Year") self.closingValues = closingValues } var body: some View { GroupBox (heading) { let xMin = closingValues.first?.timeStamp let xMax = closingValues.last?.timeStamp let yMin = closingValues.map { $0.close }.min()! let yMax = closingValues.map { $0.close }.max()! let xAxisLabels: [Date] = GetXAxisLabels(xMin: xMin!, xMax: xMax!) var yAxisLabels: [Float] { stride(from: yMin, to: yMax + ((yMax - yMin)/7), by: (yMax - yMin) / 7).map { $0 } } Chart { ForEach(closingValues) { value in LineMark( x: .value("Time", value.timeStamp!), y: .value("Closing Value", value.close) ) .foregroundStyle(Color.blue) .lineStyle(StrokeStyle(lineWidth: 1.25)) } } .chartXScale(domain: xMin!...xMax!) .chartXAxisLabel(position: .bottom, alignment: .center, spacing: 25) { Text("Date") .textFormatting(fontSize: 14) } .chartXAxis { AxisMarks(position: .bottom, values: xAxisLabels) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) AxisValueLabel(anchor: .top) { if value.as(Date.self) != nil { Text("") } } } } .chartYScale(domain: yMin...yMax) .chartYAxisLabel(position: .leading, alignment: .center, spacing: 25) { Text("Closing Value") .font(Font.custom("Arial", size: 14)) .foregroundColor(.black) } .chartYAxis { AxisMarks(position: .leading, values: yAxisLabels) { value in AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1)) AxisValueLabel() { if let labelValue = value.as(Double.self) { Text(String(format: "$ %.2f", labelValue)) .textFormatting(fontSize: 12) } } } } .chartOverlay { proxy in GeometryReader { geometry in ChartOverlayRectangle(selectedDate: $selectedDate, selectedClose: $selectedClose, proxy: proxy, geometry: geometry, xMin: xMin!, xMax: xMax!, closingValues: closingValues) } } .overlay { XAxisDates(dateLabels: xAxisLabels) } .overlay { DateAndClosingValue(selectedDate: selectedDate ?? Date(), selectedClose: selectedClose ?? 0.0) } } .groupBoxStyle(ChartGroupBoxStyle()) } }
Replies
4
Boosts
0
Views
3.1k
Activity
Jun ’23