Swift Charts

RSS for tag

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

Swift Charts Documentation

Posts under Swift Charts tag

54 Posts
Sort by:
Post not yet marked as solved
7 Replies
3.0k Views
Is there a way to create scrolling/paging behavior in the charts just like is done in the Health app? I have a similar app that also displays health data (such as heart rate and steps) and with my current custom charts the user can page back to see data from previous weeks (by default it shows the current week). Just like in the health app the user can go back as long as there is data, which can be several years (so hundreds go pages). I'd love to replace my custom implementation with Swift Charts but for that I do need this scrolling behavior.
Posted
by
Post not yet marked as solved
4 Replies
1.8k Views
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
Posted
by
Post not yet marked as solved
9 Replies
3k Views
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?
Posted
by
Post not yet marked as solved
4 Replies
1.7k Views
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.
Posted
by
Post not yet marked as solved
1 Replies
1.4k Views
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() } }
Posted
by
Post not yet marked as solved
1 Replies
930 Views
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
Posted
by
Post not yet marked as solved
0 Replies
531 Views
Everything worked fine till 14.2, the moment we upgraded to 14.3 we started getting this errors for Charts. `Undefined symbol: _$s6Charts12ChartContentPAAE15foregroundStyle2byQrAA14PlottableValueVyqd__G_tAA0G0Rd__lFQOMQ Undefined symbol: _$s6Charts12ChartContentPAAE15foregroundStyleyQrqd__7SwiftUI05ShapeE0Rd__lF Undefined symbol: _$s6Charts12ChartContentPAAE15foregroundStyleyQrqd__7SwiftUI05ShapeE0Rd__lFQOMQ Undefined symbol: _$s6Charts12ChartContentPAAE8position2by4axis4spanQrAA14PlottableValueVyqd__G_7SwiftUI4AxisOSgAA13MarkDimensionVtAA0H0Rd__lF Undefined symbol: _$s6Charts12ChartContentPAAE8position2by4axis4spanQrAA14PlottableValueVyqd__G_7SwiftUI4AxisOSgAA13MarkDimensionVtAA0H0Rd__lFQOMQ Undefined symbol: _$s6Charts14AxisMarkPresetV9automaticACvgZ Undefined symbol: _$s6Charts14AxisMarkPresetVMa Undefined symbol: _$s6Charts14AxisMarkValuesV9automaticACvgZ Undefined symbol: _$s6Charts14AxisMarkValuesVMa Undefined symbol: _$s6Charts14AxisValueLabelV8centered6anchor05multiD9Alignment19collisionResolution12offsetsMarks11orientation17horizontalSpacing08verticalO0ACys5NeverOGSbSg_7SwiftUI9UnitPointVSgAP0H0VSgAA0bcd9CollisionJ0VAoA0bcD11OrientationV12CoreGraphics7CGFloatVSgA2_tcAMRszrlufC Undefined symbol: _$s6Charts14AxisValueLabelVMn Undefined symbol: _$s6Charts14AxisValueLabelVyxGAA0B4MarkAAMc Undefined symbol: _$s6Charts14PlottableValueV5valueyACyxGqd___xtSyRd__lFZ Undefined symbol: _$s6Charts14PlottableValueVMn Undefined symbol: _$s6Charts16AxisMarkPositionV9automaticACvgZ Undefined symbol: _$s6Charts16AxisMarkPositionVMa Undefined symbol: _$s6Charts18AnnotationPositionV3topACvgZ Undefined symbol: _$s6Charts18AnnotationPositionV6bottomACvgZ Undefined symbol: _$s6Charts18AnnotationPositionV8trailingACvgZ Undefined symbol: _$s6Charts18AnnotationPositionVMa Undefined symbol: _$s6Charts18BuilderConditionalV7StorageOMn Undefined symbol: _$s6Charts18BuilderConditionalVMn Undefined symbol: _$s6Charts18BuilderConditionalVyxq_GAA12ChartContentA2aERzAaER_rlMc Undefined symbol: _$s6Charts25AxisValueLabelOrientationV9automaticACvgZ Undefined symbol: _$s6Charts25AxisValueLabelOrientationVMa Undefined symbol: _$s6Charts33AxisValueLabelCollisionResolutionV9automaticACvgZ Undefined symbol: _$s6Charts33AxisValueLabelCollisionResolutionVMa Undefined symbol: _$s6Charts5ChartV7contentACyxGxyXE_tcfC Undefined symbol: _$s6Charts5ChartVMn Undefined symbol: _$s6Charts5ChartV_2id7contentACy7SwiftUI7ForEachVyqd__qd_0_qd_1_GGqd___s7KeyPathCy7ElementQyd__qd_0_Gqd_1_ANctcAIRszSkRd__SHRd_0_AA0B7ContentRd_1_r1_lufC Undefined symbol: _$s6Charts5ChartVyxG7SwiftUI4ViewAAMc Undefined symbol: _$s6Charts7BarMarkV1x1y5width6height8stackingAcA14PlottableValueVyxG_AJyq_GAA0C9DimensionVAnA0C14StackingMethodVtcAA0G0RzAaQR_r0_lufC Undefined symbol: _$s6Charts7BarMarkVAA12ChartContentAAWP Undefined symbol: _$s6Charts7BarMarkVMa Undefined symbol: _$s6Charts7BarMarkVMn Undefined symbol: _$s6Charts8AxisMarkPAAE15foregroundStyleyQrqd__7SwiftUI05ShapeE0Rd__lF Undefined symbol: _$s6Charts8AxisMarkPAAE15foregroundStyleyQrqd__7SwiftUI05ShapeE0Rd__lFQOMQ Undefined symbol: _$s6Charts8AxisMarkPAAE4fontyQr7SwiftUI4FontVSgF Undefined symbol: _$s6Charts8AxisMarkPAAE4fontyQr7SwiftUI4FontVSgFQOMQ Undefined symbol: _$s6Charts9AxisMarksV6preset8position6values7contentACyxGAA0B10MarkPresetV_AA0bH8PositionVAA0bH6ValuesVxyctcfC Undefined symbol: _$s6Charts9AxisMarksVMn Undefined symbol: _$s6Charts9AxisMarksVyxGAA0B7ContentAAMc Undefined symbol: _$s6Charts9ScaleTypeVMa Undefined symbol: _$s6Charts9ScaleTypeVMn Undefined symbol: _$s7SwiftUI4ViewP6ChartsE10chartXAxis7contentQrqd__yXE_tAD11AxisContentRd__lF Undefined symbol: _$s7SwiftUI4ViewP6ChartsE10chartXAxis7contentQrqd__yXE_tAD11AxisContentRd__lFQOMQ Undefined symbol: _$s7SwiftUI4ViewP6ChartsE10chartXAxisyQrAA10VisibilityOF Undefined symbol: _$s7SwiftUI4ViewP6ChartsE10chartXAxisyQrAA10VisibilityOFQOMQ Undefined symbol: _$s7SwiftUI4ViewP6ChartsE10chartYAxis7contentQrqd__yXE_tAD11AxisContentRd__lF Undefined symbol: _$s7SwiftUI4ViewP6ChartsE10chartYAxis7contentQrqd__yXE_tAD11AxisContentRd__lFQOMQ Undefined symbol: _$s7SwiftUI4ViewP6ChartsE10chartYAxisyQrAA10VisibilityOF Undefined symbol: _$s7SwiftUI4ViewP6ChartsE10chartYAxisyQrAA10VisibilityOFQOMQ Undefined symbol: _$s7SwiftUI4ViewP6ChartsE25chartForegroundStyleScale6domain5range4typeQrqd___qd_0_AD0H4TypeVSgtAD0H6DomainRd__AD0H5RangeRd_0_AA05ShapeG011VisualValueRpd_0_r0_lF Undefined symbol: _$s7SwiftUI4ViewP6ChartsE25chartForegroundStyleScale6domain5range4typeQrqd___qd_0_AD0H4TypeVSgtAD0H6DomainRd__AD0H5RangeRd_0_AA05ShapeG011VisualValueRpd_0_r0_lFQOMQ Undefined symbol: _$s7SwiftUI7ForEachV6Charts7Element_2IDQZRs_AD12ChartContentR0_s12IdentifiableAERpzrlE_7contentACyxq_q0_Gx_q0_AJctcfC Undefined symbol: _$s7SwiftUI7ForEachV6ChartsAD12ChartContentR0_rlE_2id7contentACyxq_q0_Gx_s7KeyPathCy7ElementQzq_Gq0_ALctcfC Undefined symbol: _$s7SwiftUI7ForEachVyxq_q0_G6Charts12ChartContentA2eFR0_rlMc Undefined symbol: _$sSS6Charts9PlottableAAWP Undefined symbol: _$sSayxG6Charts10ScaleRangeABMc Undefined symbol: _$sSayxG6Charts11ScaleDomainA2B9PlottableRzlMc Undefined symbol: _$sSd6Charts9PlottableAAWP Linker command failed with exit code 1 (use -v to see invocation)` Can some help me to move forward on this please
Posted
by
Post marked as solved
3 Replies
1.5k Views
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()) } }
Posted
by
Post not yet marked as solved
0 Replies
311 Views
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) } }```
Posted
by
Post not yet marked as solved
2 Replies
1.2k Views
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 } }
Post not yet marked as solved
0 Replies
461 Views
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`
Posted
by
Post not yet marked as solved
0 Replies
812 Views
@Apple: Would it be possible to get the source of the Sample app shown in WWDC 2023 session “Explore pie charts and interactivity in Swift Charts” https://developer.apple.com/wwdc23/10037 In particular I’m interested in learning how to get the dates of currently be viewed bar marks in a scroll view. You can see that in the video at 9:12 on the iPhone screen showing the demo app.
Posted
by
Post not yet marked as solved
2 Replies
1.2k Views
Hi There, Same data shows different line drawing. What I am missing here ? Each time I click to see chart, its drawing is different. Chart{ ForEach(data) { series in ForEach(series.data){ entry in LineMark( x: .value("Day", entry.day), y: .value("Amount", entry.amount) ) .foregroundStyle(by: .value("Doc", series.Doc)) .symbol(by: .value("Doc", series.Doc)) PointMark( x: .value("Day", entry.day), y: .value("Sales", entry.amount) ) .foregroundStyle(.purple) .symbolSize(symbolSize) } .lineStyle(StrokeStyle(lineWidth: lineWidth)) } } .chartLegend(position: .top) .chartYScale(domain: .automatic(includesZero: false)) .chartXAxis { AxisMarks(values: .automatic(roundLowerBound: false, roundUpperBound: false)) { value in if value.index < value.count - 1 { AxisValueLabel() } AxisTick() AxisGridLine() } }
Posted
by
Post not yet marked as solved
0 Replies
865 Views
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.
Posted
by
Post not yet marked as solved
2 Replies
438 Views
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") } }
Posted
by
Post not yet marked as solved
3 Replies
1.5k Views
When using the new iOS “chartScrollableAxes” feature annotation that should show on top of the chart view no longer work. When disabling “chartScrollableAxes” everything works again. Filed as FB12584128 import SwiftUI import Charts class ChartDataEntry:Identifiable { var date:Date var value:Double init(date:Date, value: Double) { self.date=date self.value=value } } struct ContentView: View { @State var rawSelectedDate: Date? var chartData = [ChartDataEntry(date: Date().yesterday.yesterday.yesterday.yesterday.startOfDay, value: 10.0), ChartDataEntry(date: Date().yesterday.yesterday.yesterday.startOfDay, value: 20.0), ChartDataEntry(date: Date().yesterday.yesterday.startOfDay, value: 30.0), ChartDataEntry(date: Date().yesterday.startOfDay, value: 40.0), ChartDataEntry(date: Date().startOfDay, value: 50.0)] var body: some View { VStack { Chart(chartData) { entry in BarMark( x: .value("Day", entry.date, unit: .day), y: .value("Values", entry.value) ) if let selectedDate { RuleMark( x: .value("Selected", selectedDate, unit: .day)) .foregroundStyle(Color.gray.opacity(0.3)) .offset(yStart: -10) .zIndex(-1) .annotation(position: .top, spacing: -10, overflowResolution: .init( x: .fit(to: .chart), y: .disabled ) ) { Text("Longer Sample Text") } } } .chartScrollableAxes(.horizontal) // <<--- when this is disabled the annotation will be shown correctly .chartXSelection(value: $rawSelectedDate) .frame(height: 300) } .padding() } var selectedDate: Date? { guard let rawSelectedDate else { return nil } return chartData.first(where: { let endOfDay = $0.date.endOfDay return ($0.date ... endOfDay).contains(rawSelectedDate) })?.date } } #Preview { ContentView() } extension Date { var yesterday: Date { return Calendar.current.date(byAdding: .day, value: -1, to: self)! } var startOfDay: Date { return Calendar.current.startOfDay(for: self) } var endOfDay: Date { var components = DateComponents() components.day = 1 components.second = -1 return Calendar.current.date(byAdding: components, to: startOfDay)! } }
Posted
by
Post not yet marked as solved
0 Replies
595 Views
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.
Posted
by
Post not yet marked as solved
0 Replies
426 Views
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?
Posted
by
Post not yet marked as solved
3 Replies
1.3k Views
I'm currently learning Swift and SwiftUI. I'm working at a MacOS app that will need to visualize a number of traces. The user must be able to scroll along the X axis of any of the traces and the other ones should be scrolling synchronously (think about a visualization similar to Apple's own "Instruments" app). I'm using SwiftUI Charts framework for visualizing the traces, this on MacOS 14.0 (beta at the time of writing) and Xcode 15 beta 6. The app is also built against the latest MacOS target (explicitly to use the new Charts functionalities). My implementation manages to correctly synchronize the scrolling of the separate charts using a binding in combination with the chartScrollPosition method, however the scrolling performance is really terrible (the scrolling movement is sluggish and jittery). If I disable the synchronization by removing the binding and chartScrollPosition calls, the charts can be scrolled independently with no performance issues. I have the feeling that I'm making some mistake in the way I used the binding, which is causing some internal loop in the UI update/drawing process. This is also supported by the logging message I get in the console when I'm scrolling: onChange(of: Optional\<CGRect\>) action tried to update multiple times per frame. I included below the code for a test app that reproduces the issue: ContentView.swift import SwiftUI struct ContentView: View { @State private var markerValue = 0.0 var body: some View { VStack { DataTraceView(markerValue: $markerValue) } .padding() } } DataTraceView.swift import SwiftUI import Charts private let SAMPLES = 10000 func generateRandomDataPoints(count: Int) -> [DataPoint] { return (0..<count).map { idx in DataPoint(id: idx, xValue: Double(idx), yValue: Double.random(in: 0..<1)) } } struct DataPoint: Identifiable { var id: Int var xValue: Double var yValue: Double } struct DataTraceView: View { @State var testVector1: [DataPoint] = generateRandomDataPoints(count: SAMPLES) @State var testVector2: [DataPoint] = generateRandomDataPoints(count: SAMPLES) @Binding var markerValue: Double var body: some View { VStack { Chart(testVector1) { LineMark( x: .value("Time", $0.xValue), y: .value("Speed", $0.yValue) ) } .chartScrollPosition(x: $markerValue) .chartXVisibleDomain(length: 15) .chartScrollableAxes(.horizontal) Chart(testVector2) { LineMark( x: .value("Time", $0.xValue), y: .value("LatG", $0.yValue) ) } .chartScrollPosition(x: $markerValue) .chartXVisibleDomain(length: 15) .chartScrollableAxes(.horizontal) } } } Any ideas about what am I doing wrong?
Posted
by