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.6k
Sep ’23
Set Content View size/position upon retuning from navigation stack destination view
I have a program that utilizes a Navigation Stack. I want each view to be centered on the screen and be a specific size. I accomplished this with some position logic which sets the views frame size and origin. There is unique position logic for each of the 3 view sizes, the Content View and 2 navigation destination views. When the Content View is first displayed the associated position logic code runs and the view is the correct size and centered. The same is true every time one of the 2 navigation destination views is displayed. Unfortunately, when I return to the Content View from a navigation destination view the position logic does not run again and the Content View is now the same size and position as the previous navigation destination view. How do I resolve this problem? Below is the position logic code associated with the Content View and how it is called. @main struct TableViewTestApp: App { var body: some Scene { WindowGroup { ContentView() .hostingWindowPositionHome( screen: .main ) } } } extension View { func hostingWindowPositionHome( screen: NSScreen? = nil ) -> some View { modifier( WindowPositionModifierHome( screen: screen ) ) } } private struct WindowPositionModifierHome: ViewModifier { let screen: NSScreen? func body(content: Content) -> some View { content.background( HostingWindowFinderHome { $0?.setPositionHome(in: screen) } ) } } private struct HostingWindowFinderHome: NSViewRepresentable { var callback: (NSWindow?) -> () func makeNSView(context: Self.Context) -> NSView { let view = NSView() DispatchQueue.main.async { self.callback(view.window) } return view } func updateNSView(_ nsView: NSView, context: Context) { DispatchQueue.main.async { self.callback(nsView.window) } } } extension NSWindow { func setPositionHome(in screen: NSScreen?) { let nsRectangle: NSRect = NSRect(x: 1055.0, y: 370.0, width: 450, height: 700) setFrame(nsRectangle, display: true) } }
5
0
1.2k
Oct ’23
Is it possible to call openWindow() in a navigationDestination in a NavigationStack?
I have a program that uses 3 different windows, each in their own window group. In a button I can use openWindow() to call another window and it works perfectly. I watched the video at the link below and now am trying to convert my program to use a navigation stack instead of buttons. I got things to work using the code listed at the link with a few changes but am unable to get the navigation destination to use openWindow. I attempted to create a view builder but could not get it to work. After some additional research I am starting to think that the navigation destination expects to use the same window as the root view not a separate window/view and therefore, navigation destination wants just a view. But I am unsure. If someone could provide some guidance it would be appreciated. https://developer.apple.com/videos/play/wwdc2022/10054/ struct ContentView: View { @Environment (\.openWindow) private var openWindow @StateObject private var dataModel = DataModel() var body: some View { VStack(alignment: .center) { NavigationStack() { List(Sections.allCases) { section in Section(section.localizedName) { ForEach(dataModel.stocks(in: section)) { stock in NavigationLink(stock.listingName, value: stock) .font(Font.custom("Arial", size: 16)) } } // end section } // end list .scrollContentBackground(.hidden) .background(Color.mint) .navigationTitle("Stocks") .navigationDestination(for: StockData.self) { stock in Text("\(stock.listingName) - \(stock.name)") // GenericTableView(content: openWindow(id: "table", value: stock.name)) // Cannot convert value of type '()' to expected argument type '() -&gt; ContentView' } } // end navigation stack } // end v stack } } struct GenericTableView&lt;Content:View&gt;: View { let content: Content init(@ViewBuilder content: () -&gt; Content) { self.content = content() } var body: some View { content } }
1
0
731
Oct ’23
Charts module not available in Xcode 14.0.1 for macOS app
During the upgrade to Ventura it appears that Xcode was also upgraded to 14.0.1. In an attempt to use a new feature, Charts, I entered into a macOS app import Charts and I get an error message no such module Charts. If I use the same import Charts in an iOS app I do not get such an error. I am wondering if Charts in not available for macOS apps or did something go wrong during the Ventura upgrade. If it is the later, it makes sense to me to cleanly uninstall Xcode and reinstall. But it is unclear if just dragging Xcode from the application folder to the trash and emptying the trash completely uninstalls Xcode. As a side note, I do not ever remember Xcode being upgraded during an upgrade to macOS. Any input will be appreciated.
1
1
1.8k
Oct ’22
Charts: How do I position x axis value labels below the associated grid lines
I am working with the new Charts Framework. The axis value labels for the x axis are dates (mm/dd/yy). I have 5 vertical grid lines and am trying to get the dates to be centered below the associated grid line with no success. One additional problem is that the values are in an array that contains 5 dates but only the first 4 get displayed. Any solutions will be appreciated. Below is the code. struct LineChart: View { private var localArray: [TradingDayPrices] init(passedInArray: [TradingDayPrices]) { self.localArray = passedInArray } var body: some View { let minCloseValue: Double = localArray.map { $0.close }.min()! let maxCloseValue: Double = localArray.map { $0.close }.max()! let minDate: Date = localArray[0].timeStamp! let itemCount: Int = localArray.count - 1 let maxDate: Date = localArray[itemCount].timeStamp! Spacer() GroupBox (label: Text("VOO Closing Values For The Past Year") .font(.system(size: 20)) .fontWeight(.bold) .frame(width: 700, height: 50, alignment: .center)) { Chart { ForEach(localArray) { item in LineMark ( x: .value("TimeStamp", item.timeStamp!), y: .value("Close", item.close) ) .foregroundStyle(Color.blue) .lineStyle(StrokeStyle(lineWidth: 1.25)) } // end for each } // end chart .padding(50) .chartBackground { item in Color.white } .chartXAxisLabel(position: .bottom, alignment: .center) { Text("Date") .font(.system(size: 14)) .foregroundColor(Color.black) .frame(width: 50, height: 35, alignment: .bottom) } .chartYAxisLabel(position: .leading, alignment: .center, spacing: 0) { Text("Closing Values") .font(.system(size: 14)) .foregroundColor(Color.black) } .chartXAxis { AxisMarks (values: GetXAxisLabels(min: minDate, max: maxDate)) { value in AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5)) .foregroundStyle(Color.gray) AxisValueLabel() { if let localDate = value.as(Date.self) { let formattedDate = dateToStringFormatter.string(from: localDate) Text(formattedDate) .font(.system(size: 12)) .foregroundColor(Color.black) } } // end axis value label } // end axis marks } // end chart x axis .chartYAxis { AxisMarks (position: .leading, values: GetYAxisLabels(min: minCloseValue, max: maxCloseValue)) { value in AxisGridLine(stroke: StrokeStyle(lineWidth: 0.5)) .foregroundStyle(Color.gray) AxisValueLabel() { if let localValue = value.as(Double.self) { let formattedValue = String(format: "$%.2f", localValue) Text(formattedValue) .font(.system(size: 12)) .foregroundColor(Color.black) } } } // end axis marks } // end chart y axis .chartXScale(domain: minDate...maxDate) .chartYScale(domain: minCloseValue...maxCloseValue) .frame(width: 700, height: 700, alignment: .center) } // end group box } // end of body } // end of structure func GetXAxisLabels(min: Date, max: Date) -> [Date] { var xLabels: [Date] = [] let increment: Int = 90 for i in 0...3 { let value = Calendar.current.date(byAdding: DateComponents(day: (i * increment)), to: min)! xLabels.append(value) } xLabels.append(max) print("\(xLabels)") return xLabels } func GetYAxisLabels(min: Double, max: Double) -> [Double] { var yLabels: [Double] = [] let increment: Double = (max - min) / 4 for i in 0...3 { let value = min + (Double(i) * increment) yLabels.append(value) } yLabels.append(max) return yLabels } let dateToStringFormatter: DateFormatter = { let result = DateFormatter() result.dateFormat = "MM/dd/yy" return result }()
2
1
3.9k
Jan ’23