图表符号和图例符号在SwiftUI中不同。

huangapple go评论67阅读模式
英文:

Chart Symbols and Legend Symbols Are Diferent in SwiftUI

问题

图表中使用.symbol(by:)修饰符生成的图例符号与图表中使用的符号不同。我特别在图表中使用了三角形和加号符号,但它们被忽略了,自动在图例部分生成了圆圈和方形符号。如何使它们一致?

以下是修复代码:

struct Line: Identifiable {
    let xyzipped: [(Double, Double)]
    let symbol: BasicChartSymbolShape
    let legendStr: String
    let id = UUID()
    
    init(x: [Double],
         y: [Double],
         symbol: BasicChartSymbolShape,
         legendStr: String)
    {
        self.xyzipped = Array(zip(x, y))
        self.symbol = symbol
        self.legendStr = legendStr
    }
}

struct ChartOfLines: View {
    let lines: [Line]
    
    init() {
        let line1 = Line(x: [0, 1, 2, 3, 4],
                         y: [3, 5, 8, -1, 0],
                         symbol: BasicChartSymbolShape.triangle,
                         legendStr: "line1")
        let line2 = Line(x: [0, 1, 2, 3, 4],
                         y: [5, 4, 3, 7, 1],
                         symbol: BasicChartSymbolShape.plus,
                         legendStr: "line2")
        
        lines = [line1, line2]
    }
    
    var body: some View {
        Chart(lines, id: \.id) { line in
            ForEach(line.xyzipped, id:\.0) { xy in
                LineMark(
                    x: .value("X values", xy.0),
                    y: .value("Y values", xy.1)
                )
                .lineStyle(StrokeStyle(lineWidth: 0.5))
                
                PointMark(
                    x: .value("X values", xy.0),
                    y: .value("Y values", xy.1)
                )
            }
            .symbol(line.symbol)
            .symbol(by: .value("", line.legendStr))
            .foregroundStyle(by: .value("", line.legendStr))
        }
        .frame(width: 500, height: 500)
        .padding()
    }
}

这将确保图例中的符号与图表中使用的一致。

英文:

Legend symbols produced by the .symbol(by:) modifier are different than the ones used in the chart. I specifically used the triangle and plus symbols in the chart, but they are disregarded and the circle and square symbols are produced automatically in the legend part. How can I make them agree?

struct Line: Identifiable {
    let xyzipped: [(Double, Double)]
    let symbol: BasicChartSymbolShape
    let legendStr: String
    let id = UUID()
    
    init(x: [Double],
         y: [Double],
         symbol: BasicChartSymbolShape,
         legendStr: String)
    {
        self.xyzipped = Array(zip(x, y))
        self.symbol = symbol
        self.legendStr = legendStr
    }
}


struct ChartOfLines: View {
    let lines: [Line]
    
    init() {
        let line1 = Line(x: [0, 1, 2, 3, 4],
                         y: [3, 5, 8, -1, 0],
                         symbol: BasicChartSymbolShape.triangle,
                         legendStr: "line1")
        let line2 = Line(x: [0, 1, 2, 3, 4],
                         y: [5, 4, 3, 7, 1],
                         symbol: BasicChartSymbolShape.plus,
                         legendStr: "line2")
        
        lines = [line1, line2]
    }
    
    var body: some View {
        Chart(lines, id: \.id) { line in
            ForEach(line.xyzipped, id:\.0) { xy in
                LineMark(
                    x: .value("X values", xy.0),
                    y: .value("Y values", xy.1)
                )
                .lineStyle(StrokeStyle(lineWidth: 0.5))
                
                PointMark(
                    x: .value("X values", xy.0),
                    y: .value("Y values", xy.1)
                )
            }
            .symbol(line.symbol)
            .symbol(by: .value("", line.legendStr))
            .foregroundStyle(by: .value("", line.legendStr))
        }
        .frame(width: 500, height: 500)
        .padding()
    }
}

Here is the produced chart:
图表符号和图例符号在SwiftUI中不同。

答案1

得分: 2

创建一个自定义的 chartLegend,如果你希望 ChartSymbolShape 出现在图例字符串的左侧:

测试示例,根据需要调整 UI:

struct Line: Identifiable {
    let xyzipped: [(Double, Double)]
    let symbol: BasicChartSymbolShape
    let legendStr: String
    let lineColor: Color
    let id = UUID()
    
    init(x: [Double],
         y: [Double],
         symbol: BasicChartSymbolShape,
         legendStr: String,
         lineColor: Color)
    {
        self.xyzipped = Array(zip(x, y))
        self.symbol = symbol
        self.legendStr = legendStr
        self.lineColor = lineColor
    }
}

struct ContentView: View {
    let lines: [Line]
    
    init() {
        let line1 = Line(x: [0, 1, 2, 3, 4],
                         y: [3, 5, 8, -1, 0],
                         symbol: BasicChartSymbolShape.triangle,
                         legendStr: "line1", lineColor: .green)
        let line2 = Line(x: [0, 1, 2, 3, 4],
                         y: [5, 4, 3, 7, 1],
                         symbol: BasicChartSymbolShape.plus,
                         legendStr: "line2", lineColor: .blue)
        
        lines = [line1, line2]
    }
    
    var body: some View {
        Chart(lines, id: \.id) { line in
            ForEach(line.xyzipped, id:\.0) { xy in
                LineMark(
                    x: .value("X values", xy.0),
                    y: .value("Y values", xy.1)
                )
                .lineStyle(StrokeStyle(lineWidth: 0.5))
                .foregroundStyle(line.lineColor)
                
                PointMark(
                    x: .value("X values", xy.0),
                    y: .value("Y values", xy.1)
                )
                .foregroundStyle(line.lineColor)
            }
            .symbol(line.symbol)
            .foregroundStyle(by: .value("", line.legendStr))
        }
        .chartLegend(position: .bottomLeading, alignment: .bottomLeading) {
            HStack() {
                ForEach(lines) { xy in
                    HStack {
                        xy.symbol
                            .frame(width: 10, height: 10)
                            .foregroundColor(xy.lineColor)
                        Text(xy.legendStr).foregroundColor(.black)
                    }
                }
            }
        }
        .frame(width: 500, height: 500)
        .padding()
    }
}
英文:

Create a custom chartLegend if you want the ChartSymbolShape to appear to the left of the legend string:

Example to test, adjust UI as necessary:

struct Line: Identifiable {
    let xyzipped: [(Double, Double)]
    let symbol: BasicChartSymbolShape
    let legendStr: String
    let lineColor: Color
    let id = UUID()
    
    init(x: [Double],
         y: [Double],
         symbol: BasicChartSymbolShape,
         legendStr: String,
         lineColor: Color)
    {
        self.xyzipped = Array(zip(x, y))
        self.symbol = symbol
        self.legendStr = legendStr
        self.lineColor = lineColor
    }
}


struct ContentView: View {
    let lines: [Line]
    
    init() {
        let line1 = Line(x: [0, 1, 2, 3, 4],
                         y: [3, 5, 8, -1, 0],
                         symbol: BasicChartSymbolShape.triangle,
                         legendStr: "line1", lineColor: .green)
        let line2 = Line(x: [0, 1, 2, 3, 4],
                         y: [5, 4, 3, 7, 1],
                         symbol: BasicChartSymbolShape.plus,
                         legendStr: "line2", lineColor: .blue)
        
        
        lines = [line1, line2]
    }
    
    var body: some View {
        Chart(lines, id: \.id) { line in
            ForEach(line.xyzipped, id:\.0) { xy in
                LineMark(
                    x: .value("X values", xy.0),
                    y: .value("Y values", xy.1)
                )
                .lineStyle(StrokeStyle(lineWidth: 0.5))
                .foregroundStyle(line.lineColor)
                
                PointMark(
                    x: .value("X values", xy.0),
                    y: .value("Y values", xy.1)
                )
                .foregroundStyle(line.lineColor)
            }
            .symbol(line.symbol)
            .foregroundStyle(by: .value("", line.legendStr))
        }
        .chartLegend(position: .bottomLeading, alignment: .bottomLeading) {
            HStack() {
                ForEach(lines) { xy in
                    HStack {
                        xy.symbol
                            .frame(width: 10, height: 10)
                            .foregroundColor(xy.lineColor)
                        Text(xy.legendStr).foregroundColor(.black)
                    }
                }
            }
        }
        .frame(width: 500, height: 500)
        .padding()
    }
}

huangapple
  • 本文由 发表于 2023年2月6日 07:48:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75356314.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定