Home > Net >  Is it possible to use an SFSymbol in a Swift Chart for a bar mark?
Is it possible to use an SFSymbol in a Swift Chart for a bar mark?

Time:11-05

I want to use symbols in a bar chart to represent a habit the user specifies. Text can be too long and gets cut off by the next chart.

Here is what I tried:

Chart {
    ForEach(habitItems) { habit in
        BarMark(x: .value("Type", Image(systemName: habit.symbolHI)),
                y: .value("Tracked", countTrackedDates(for: habit))
                )
        .foregroundStyle(getBarColor(for: habit).gradient)
        .cornerRadius(20)
    }
}

habit.symbolHI would equal a string for example: "square.fill"

I am getting an error:

Initializer 'init(x:y:width:height:stacking:)' requires that 'Image' conform to 'Plottable'

Maybe there is a way to make an image plottable but I'm not sure how.

CodePudding user response:

For simplicity, I'll assume you have an array of these:

struct Habit: Identifiable {
    let symbolName: String
    let count: Int
    let color: Color
    
    var id: String { symbolName }
}

You can just plot the name of the image.

BarMark(x: .value("Type", habit.symbolName),
        y: .value("Tracked", habit.count)
        )

Then use chartXAxis to change the X axis marks to images:

Chart {
    ...
}
.chartXAxis {
    AxisMarks { value in
        AxisValueLabel {
            Image(systemName: value.as(String.self)!)
                .font(.system(size: 30))
        }
    }
}

I am casting value to String here because I know I'm plotting strings on the x axis (as in x: .value("Type", habit.symbolName)). You can also use habitItems[value.index].symbolName if the indices of the x axis marks match the indices of your data (this would work if the data is an Array, but would not be the case if it is an ArraySlice in the middle of an array for example).

  • Related