skip to Main Content

here are two charts.
and I would like to show the data of object and object2 together in one chart.

Would it be possible?

Chart(db.objects, id: .self) { object in
    LineMark(
        x: .value("name", object.name),
        y: .value("value", Int(object.value) ?? 0)
    )
}

Chart(db.objects2, id: .self) { object2 in
    LineMark(
        x: .value("name", object2.name),
        y: .value("value", Int(object2.value) ?? 0)
    )
}

3

Answers


  1. Chosen as BEST ANSWER

    I just found the way from apple developer website

    https://developer.apple.com/documentation/charts/chart/

    struct ProfitOverTime {
        var date: Date
        var profit: Double
    }
    
    let departmentAProfit: [ProfitOverTime] = [] // ...
    let departmentBProfit: [ProfitOverTime] = [] // ...
    
    var body: some View {
        Chart {
            ForEach(departmentAProfit) {
                LineMark(
                    x: .value("Date", $0.date),
                    y: .value("Profit A", $0.profit)
                )
                .foregroundStyle(.blue)
            }
            ForEach(departmentBProfit) {
                LineMark(
                    x: .value("Date", $0.date),
                    y: .value("Profit B", $0.profit)
                )
                .foregroundStyle(.green)
            }
            RuleMark(
                y: .value("Threshold", 500.0)
            )
            .foregroundStyle(.red)
        }
    }
    

    chart showing overlaid data


  2. This is an alternative solution. Since the data structure is the same, the data could be one source and displayed using one LineMark.

    As an example, dept was added to the model to identify each group of data that represents a single line in the chart:

        struct ProfitOverTime {
            var dept: String
            var date: Date
            var profit: Double
        }
    

    The data combined into one array:

        let data: [ProfitOverTime] = [] // ...
    

    The foreground style is based on the department, that is, each line in the chart.

    struct DepartmentChart: View {
        var body: some View {
            Chart(data) {
                LineMark(
                    x: .value("Date", $0.date),
                    y: .value("Profit", $0.profit)
                    series: .value("Department", $0.dept)
                )
                .foregroundStyle(by: .value("Department", $0.dept))
        
                RuleMark(
                    y: .value("Threshold", 500.0)
                )
                .foregroundStyle(.red)
            }
            .chartForegroundStyleScale(["Profit A": .green, "Profit B": .blue])
        }
    }
    

    Series was added to identify each line by its color:

    enter image description here

    The chartForegroundStyleScale is optional since each line will automatically be colored differently. But chartForegroundStyleScale can be used to customize the line colors.

    Login or Signup to reply.
  3. Here I am showing the data for a week. So if you want to show more than data then you can increase the number of entries. So that’s it from my side hope you understand.

    Now use MultiLineChartView like this.

    Complete Code:

    import SwiftUI
    import Charts
    
    struct ContentView: View {
        let days = ["S", "M", "T", "W", "T", "F", "S"]
        let entries1 = [
            ChartDataEntry(x: 1, y: 1),
            ChartDataEntry(x: 2, y: 2),
            ChartDataEntry(x: 3, y: 0),
            ChartDataEntry(x: 4, y: 0),
            ChartDataEntry(x: 5, y: 0),
            ChartDataEntry(x: 6, y: 0),
            ChartDataEntry(x: 7, y: 1),
            
        ]
        let entries2 = [
            ChartDataEntry(x: 1, y: 2),
            ChartDataEntry(x: 2, y: 3),
            ChartDataEntry(x: 3, y: 0),
            ChartDataEntry(x: 4, y: 0),
            ChartDataEntry(x: 5, y: 0),
            ChartDataEntry(x: 6, y: 0),
            ChartDataEntry(x: 7, y: 2)
        ]
        var body: some View {
            VStack{
                Spacer()
                MultiLineChartView(entries1: entries1, entries2: entries2, days: days)
                .frame(height: 220)
                Spacer()
            }
        }
    }
    
    struct MultiLineChartView : UIViewRepresentable {
        
        var entries1 : [ChartDataEntry]
        var entries2 : [ChartDataEntry]
        var days: [String]
        
        func makeUIView(context: Context) -> LineChartView {
            let chart = LineChartView()
            return createChart(chart: chart)
        }
        
        func updateUIView(_ uiView: LineChartView, context: Context) {
            uiView.data = addData()
        }
        
        func createChart(chart: LineChartView) -> LineChartView{
            chart.chartDescription?.enabled = false
            chart.xAxis.drawGridLinesEnabled = false
            chart.xAxis.drawLabelsEnabled = true
            chart.xAxis.drawAxisLineEnabled = false
            chart.xAxis.labelPosition = .bottom
            chart.rightAxis.enabled = false
            chart.leftAxis.enabled = false
            chart.drawBordersEnabled = false
            chart.legend.form = .none
            chart.xAxis.labelCount = 7
            chart.xAxis.forceLabelsEnabled = true
            chart.xAxis.granularityEnabled = true
            chart.xAxis.granularity = 1
            chart.xAxis.valueFormatter = CustomChartFormatter(days: days)
            
            chart.data = addData()
            return chart
        }
        
        func addData() -> LineChartData{
            let data = LineChartData(dataSets: [
                //Schedule Trips Line
                generateLineChartDataSet(dataSetEntries: entries1, color: UIColor(Color(#colorLiteral(red: 0.6235294118, green: 0.7333333333, blue: 0.3568627451, alpha: 1))), fillColor: UIColor(Color(#colorLiteral(red: 0, green: 0.8134518862, blue: 0.9959517121, alpha: 1)))),
                //Unloadings Line
                generateLineChartDataSet(dataSetEntries: entries2, color: UIColor(Color(#colorLiteral(red: 0.003921568627, green: 0.231372549, blue: 0.431372549, alpha: 1))), fillColor: UIColor(Color(#colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1))))
            ])
            return data
        }
        
        func generateLineChartDataSet(dataSetEntries: [ChartDataEntry], color: UIColor, fillColor: UIColor) -> LineChartDataSet{
            let dataSet = LineChartDataSet(entries: dataSetEntries, label: "")
            dataSet.colors = [color]
            dataSet.mode = .cubicBezier
            dataSet.circleRadius = 5
            dataSet.circleHoleColor = UIColor(Color(#colorLiteral(red: 0.003921568627, green: 0.231372549, blue: 0.431372549, alpha: 1)))
            dataSet.fill = Fill.fillWithColor(fillColor)
            dataSet.drawFilledEnabled = true
            dataSet.setCircleColor(UIColor.clear)
            dataSet.lineWidth = 2
            dataSet.valueTextColor = color
            dataSet.valueFont = UIFont(name: "Avenir", size: 12)!
            return dataSet
        }
        
    }
    
    class CustomChartFormatter: NSObject, IAxisValueFormatter {
        var days: [String]
        
        init(days: [String]) {
            self.days = days
        }
        
        public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
            return days[Int(value-1)]
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search