willdale / SwiftUICharts

A charts / plotting library for SwiftUI. Works on macOS, iOS, watchOS, and tvOS and has accessibility features built in.
MIT License
865 stars 107 forks source link

Padding not respected #144

Open ahartman opened 2 years ago

ahartman commented 2 years ago

In landscape the scales are drawn into the padding area. In portrait the same happens; additionally the horizontal padding is not respected.

See images below. Simulator Screen Shot - iPhone SE (2nd generation) - 2021-11-30 at 08 49 40

Simulator Screen Shot - iPhone SE (2nd generation) - 2021-11-30 at 08 49 55

willdale commented 2 years ago

Can you post your view code please?

It looks like (maybe) the view modifiers are out of sequence .

ahartman commented 2 years ago

Dear Will Dale,

Thank you for the quick answer. Even if this is a view modifier order issue, I would still not expect the app to crash. Please find the whole project attached.

The two graphs are in IntraGraphView and InterGraphView; these are action sheets in IntradayView and InterdayView. The app gets data from a REST interface on my NAS. You will have to mock up some data to get the app to run.

As you can see in the images that I included in my to issues, it also seems that padding and margins are not respected in the width. This may be a connected issue.

I hope you can find to fix this.

Met vriendelijke groeten, Kind regards, Meilleures salutations, André Hartman

Op 1 dec. 2021, om 21:18 heeft Will Dale @.***> het volgende geschreven:

Can you post your view code please?

It looks like (maybe) the view modifiers are out of sequence .

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/willdale/SwiftUICharts/issues/144#issuecomment-984022011, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFIBPFMUOX3RKMFMYB5GWTUOZ7LFANCNFSM5JBCWSDQ. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

willdale commented 2 years ago

Hi @ahartman, the crash is a separate issue, in this issue we are talking solely about the view layout.

I can't see a project and I don't open projects from unknown sources. Can you post just the view code?

Thanks, Will

ahartman commented 2 years ago

Dear Will Dale,

Please find the code below:

import SwiftUI
import SwiftUICharts

struct IntraGraphView: View {
    @EnvironmentObject var viewModel: ViewModel
    @Binding var showGraphView: Bool

    let data: MultiLineChartData = makeData()
    let extraLineData = makeExtra()
    static var yLabelsNumber = 10

    var body: some View {
        NavigationView {
            VStack {
                MultiLineChart(chartData: data)
                    .extraLine(chartData: data,
                               legendTitle: "Index",
                               datapoints: extraLineData,
                               style: extraLineStyle)
                    .xAxisGrid(chartData: data)
                    .yAxisGrid(chartData: data)
                    .xAxisLabels(chartData: data)
                    .yAxisLabels(chartData: data, specifier: "%.2f")
                    .extraYAxisLabels(chartData: data, colourIndicator: .style(size: 12))
                    .legends(chartData: data, columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())])
                    .id(data.id)
                    .padding(20.0)
                    .frame(width: geo.size.width * 0.9, height: geo.size.height * 0.9, alignment: .bottom)
                    .navigationBarTitle("Intraday waarde en index", displayMode: .inline)
                    .navigationBarItems(leading:
                        Button(action: { showGraphView = false })
                            { Image(systemName: "table") })
            }
        }
    }

    private var extraLineStyle: ExtraLineStyle {
        ExtraLineStyle(lineColour: ColourStyle(colour: .black),
                       lineType: .line,
                       lineSpacing: .line,
                       yAxisTitle: "Index",
                       yAxisNumberOfLabels: IntraGraphView.yLabelsNumber,
                       animationType: .raise,
                       baseline: .minimumValue)
    }

    static func makeData() -> MultiLineChartData {
        let data = ViewModel().intraday.graphDataL
        let gridStyle = GridStyle(numberOfLines: yLabelsNumber,
                                  lineColour: Color.gray.opacity(0.75))

        return MultiLineChartData(dataSets: data,
                                  chartStyle: LineChartStyle(xAxisGridStyle: gridStyle,
                                                             xAxisLabelsFrom: .dataPoint(rotation: .degrees(-90)),
                                                             xAxisTitle: "Datums",
                                                             yAxisGridStyle: gridStyle,
                                                             yAxisNumberOfLabels: yLabelsNumber,
                                                             yAxisTitle: "Mutatie in €",
                                                             baseline: .minimumValue,
                                                             topLine: .maximumValue))
    }

    static func makeExtra() -> [ExtraLineDataPoint] {
        return ViewModel().intraday.extraLine
    }
}
willdale commented 2 years ago

Hey @ahartman, thanks. Does the MultiLineChart have the same issue as the RangedBarChart pictured above?

ahartman commented 2 years ago

Dear Will Dale,

Yes, it certainly does.

Met vriendelijke groeten, Kind regards, Meilleures salutations, André Hartman

Op 7 dec. 2021, om 08:39 heeft Will Dale @.***> het volgende geschreven:

Hey @ahartman https://github.com/ahartman, thanks. Does the MultiLineChart have the same issue as the RangedBarChart pictured above?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/willdale/SwiftUICharts/issues/144#issuecomment-987650844, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFIBPDXODSBCGWGBULWCATUPW2ZJANCNFSM5JBCWSDQ. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

ahartman commented 2 years ago

Dear Will Dale,

The code I posted this morning is incorrect as it is without GeometryReader. Please find corrected code below. The crash seems to be caused by the use of 'geo' in .frame.

If you leave GeometryReader in but comment out the .frame line using geo and uncomment the .frame line that does NOT use geo, the crash does not occur. This is identical for the StackedBarchart as well as the MultiLineChart.

The crash is reported on a line in ExtraLine.swift, see attached image. I hope this helps.

Code WITH GemoteryReader:

import SwiftUI import SwiftUICharts

struct IntraGraphView: View { @EnvironmentObject var viewModel: ViewModel @Binding var showGraphView: Bool

let data: MultiLineChartData = makeData()
let extraLineData = makeExtra()
static var yLabelsNumber = 10

var body: some View {
    GeometryReader { geo in
        NavigationView {
            VStack {
                MultiLineChart(chartData: data)
                    .extraLine(chartData: data,
                               legendTitle: "Index",
                               datapoints: extraLineData,
                               style: extraLineStyle)
                    .xAxisGrid(chartData: data)
                    .yAxisGrid(chartData: data)
                    .xAxisLabels(chartData: data)
                    .yAxisLabels(chartData: data, specifier: "%.2f")
                    .extraYAxisLabels(chartData: data, colourIndicator: .style(size: 12))
                    .legends(chartData: data, columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())])
                    .id(data.id)
                    .padding(20.0)
                    .frame(width: geo.size.width * 0.9, height: geo.size.height * 0.9, alignment: .bottom)
                    //.frame(minWidth: 150, maxWidth: 900, minHeight: 150, idealHeight: 500, maxHeight: 600, alignment: .center)
                    .navigationBarTitle("Intraday waarde en index", displayMode: .inline)
                    .navigationBarItems(leading:
                        Button(action: { showGraphView = false })
                            { Image(systemName: "table") })
            }
        }
    }
}

private var extraLineStyle: ExtraLineStyle {
    ExtraLineStyle(lineColour: ColourStyle(colour: .black),
                   lineType: .line,
                   lineSpacing: .line,
                   yAxisTitle: "Index",
                   yAxisNumberOfLabels: IntraGraphView.yLabelsNumber,
                   animationType: .raise,
                   baseline: .minimumValue)
}

static func makeData() -> MultiLineChartData {
    let data = ViewModel().intraday.graphDataL
    let gridStyle = GridStyle(numberOfLines: yLabelsNumber,
                              lineColour: Color.gray.opacity(0.75))

    return MultiLineChartData(dataSets: data,
                              chartStyle: LineChartStyle(xAxisGridStyle: gridStyle,
                                                         xAxisLabelsFrom: .dataPoint(rotation: .degrees(-90)),
                                                         xAxisTitle: "Datums",
                                                         yAxisGridStyle: gridStyle,
                                                         yAxisNumberOfLabels: yLabelsNumber,
                                                         yAxisTitle: "Mutatie in €",
                                                         baseline: .minimumValue,
                                                         topLine: .maximumValue))
}

static func makeExtra() -> [ExtraLineDataPoint] {
    return ViewModel().intraday.extraLine
}

}

Image of crash location:

Schermafbeelding 2021-12-07 om 09 32 45
ahartman commented 2 years ago

Dear Will Dale, I had a brain wave with surprising effects, reversing NavigationView and GeometryReader and placing GeometryReader INSIDE NavigationView. The crash now no longer occurs but the ExtraLine is now displayed three times in the chart legend in portrait mode and five times in landscape. Both charts have this behaviour, totally weird!

See images below. The first image is with NavigationView inside GeometryReader, the second is with order reversed, GeometryReader inside Navigationview.

Simulator Screen Shot - iPhone SE (2nd generation) - 2021-12-07 at 09 40 09

Simulator Screen Shot - iPhone SE (2nd generation) - 2021-12-07 at 09 41 11