Open dadixon opened 2 years ago
Same
The data is already being parsed but it's not implemented in the code for some reason. You can try editing it like below. (this is specifically for BarChart)
Look for the code comment "// BarChartLabel"
import SwiftUI
/// A single row of data, a view in a `BarChart`
public struct BarChartRow: View {
@EnvironmentObject var chartValue: ChartValue
@ObservedObject var chartData: ChartData
@State private var touchLocation: CGFloat = -1.0
var style: ChartStyle
var maxValue: Double {
guard let max = chartData.points.max() else {
return 1
}
return max != 0 ? max : 1
}
/// The content and behavior of the `BarChartRow`.
///
/// Shows each `BarChartCell` in an `HStack`; may be scaled up if it's the one currently being touched.
/// Not using a drawing group for optimizing animation.
/// As touched (dragged) the `touchLocation` is updated and the current value is highlighted.
public var body: some View {
GeometryReader { geometry in
HStack(alignment: .bottom,
spacing: geometry.frame(in: .local).width / CGFloat(chartData.data.count * 3)) {
ForEach(0..<chartData.data.count, id: \.self) { index in
BarChartCell(value: chartData.normalisedPoints[index],
index: index,
gradientColor: self.style.foregroundColor.rotate(for: index),
touchLocation: self.touchLocation,
label: self.chartData.values[index]) // BarChartLabel
.scaleEffect(self.getScaleSize(touchLocation: self.touchLocation, index: index), anchor: .bottom)
.animation(Animation.easeIn(duration: 0.2))
}
// .drawingGroup()
}
.frame(maxHeight: chartData.isInNegativeDomain ? geometry.size.height / 2 : geometry.size.height)
.gesture(DragGesture()
.onChanged({ value in
let width = geometry.frame(in: .local).width
self.touchLocation = value.location.x/width
if let currentValue = self.getCurrentValue(width: width) {
self.chartValue.currentValue = currentValue
self.chartValue.interactionInProgress = true
}
})
.onEnded({ value in
self.chartValue.interactionInProgress = false
self.touchLocation = -1
})
)
}
}
/// Size to scale the touch indicator
/// - Parameters:
/// - touchLocation: fraction of width where touch is happening
/// - index: index into data array
/// - Returns: a scale larger than 1.0 if in bounds; 1.0 (unscaled) if not in bounds
func getScaleSize(touchLocation: CGFloat, index: Int) -> CGSize {
if touchLocation > CGFloat(index)/CGFloat(chartData.data.count) &&
touchLocation < CGFloat(index+1)/CGFloat(chartData.data.count) {
return CGSize(width: 1.4, height: 1.1)
}
return CGSize(width: 1, height: 1)
}
/// Get data value where touch happened
/// - Parameter width: width of chart
/// - Returns: value as `Double` if chart has data
func getCurrentValue(width: CGFloat) -> Double? {
guard self.chartData.data.count > 0 else { return nil}
let index = max(0,min(self.chartData.data.count-1,Int(floor((self.touchLocation*width)/(width/CGFloat(self.chartData.data.count))))))
return self.chartData.points[index]
}
}
struct BarChartRow_Previews: PreviewProvider {
static let chartData = ChartData([6, 2, 5, 6, 7, 8, 9])
static let chartData2 = ChartData([("M",6), ("T",2), ("W",5), ("T",6), ("F",7), ("S",8), ("S",9)])
static let chartStyle = ChartStyle(backgroundColor: .white, foregroundColor: .orangeBright)
static var previews: some View {
VStack{
BarChartRow(chartData: chartData, style: chartStyle)
.border(.red)
.frame(width: 100, height: 100)
HStack (alignment: .lastTextBaseline){
VStack {
Text("Load")
Text("400")
}
Spacer()
BarChartRow(chartData: chartData2, style: chartStyle)
.border(.red)
.frame(width: 150, height: 50)
}
}
.padding([.leading, .trailing],10)
}
}
BarChartCell
import SwiftUI
/// A single vertical bar in a `BarChart`
public struct BarChartCell: View {
var value: Double
var index: Int = 0
var gradientColor: ColorGradient
var touchLocation: CGFloat
var label: String = "" // BarChartLabel
@State private var didCellAppear: Bool = false
public init( value: Double,
index: Int = 0,
gradientColor: ColorGradient,
touchLocation: CGFloat,
label: String = "") { // BarChartLabel
self.value = value
self.index = index
self.gradientColor = gradientColor
self.touchLocation = touchLocation
self.label = label // BarChartLabel
}
/// The content and behavior of the `BarChartCell`.
///
/// Animated when first displayed, using the `firstDisplay` variable, with an increasing delay through the data set.
public var body: some View {
VStack{ // BarChartLabel - Embed it into a Stack
BarChartCellShape(value: didCellAppear ? value : 0.0)
.fill(gradientColor.linearGradient(from: .bottom, to: .top))
.onAppear {
self.didCellAppear = true
}
.onDisappear {
self.didCellAppear = false
}
.transition(.slide)
.animation(Animation.spring().delay(self.touchLocation < 0 || !didCellAppear ? Double(self.index) * 0.04 : 0))
Text(String(label)) // BarChartLabel
.font(.caption). // BarChartLabel
}
}
}
struct BarChartCell_Previews: PreviewProvider {
static var previews: some View {
Group {
Group {
BarChartCell(value: 0, gradientColor: ColorGradient.greenRed, touchLocation: CGFloat(), label: "POPO")
BarChartCell(value: 0.5, gradientColor: ColorGradient.greenRed, touchLocation: CGFloat())
BarChartCell(value: 0.75, gradientColor: ColorGradient.whiteBlack, touchLocation: CGFloat())
BarChartCell(value: 1, gradientColor: ColorGradient(.purple), touchLocation: CGFloat())
}
Group {
BarChartCell(value: 1, gradientColor: ColorGradient.greenRed, touchLocation: CGFloat())
BarChartCell(value: 1, gradientColor: ColorGradient.whiteBlack, touchLocation: CGFloat())
BarChartCell(value: 1, gradientColor: ColorGradient(.purple), touchLocation: CGFloat())
}.environment(\.colorScheme, .dark)
}
}
}
struct ContentView: View {
// var demoData: [String, Double] = [("M",1.0),("T",2.0),("W",4.0), ("T", 8.0), ("F",10.0), ("S",9.0),("S", 2.0)]
var demoData: [(String, Double)] = ([("M",9), ("T",2), ("W",5), ("T",6), ("F",7), ("S",8), ("S",9)])
var demoData2: [(String, Double)] = ([("M",1), ("T",11), ("W",12), ("T",6), ("F",11), ("S",0), ("S",7)])
var demoData3: [(String, Double)] = ([("M",1.55), ("T",2.1), ("W",1.6), ("T",0.3), ("F",0.9), ("S",1.3), ("S",2.0)])
var body: some View {
VStack {
Text("Hello, world!")
HStack{
CardView(showShadow: true) {
Text("Load")
.padding([.leading, .top],10)
.font(.caption)
ChartLabel("400", type: .custom(size: 10, padding: EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0), color: Color(UIColor.secondaryLabel)), format: "%0.0f")
BarChart()
.padding(.horizontal,10)
.padding(.bottom,5)
}
.data(demoData)
.chartStyle(ChartStyle(backgroundColor: .white,
foregroundColor: [ColorGradient(.blue, .purple)]
))
CardView(showShadow: true) {
Text("Distance")
.padding([.leading, .top],10)
.font(.caption)
ChartLabel("400km", type: .custom(size: 10, padding: EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0), color: Color(UIColor.secondaryLabel)), format: "%0.0f")
BarChart()
.padding(.horizontal,10)
.padding(.bottom,5)
}
.data(demoData2)
.chartStyle(ChartStyle(backgroundColor: .white,
foregroundColor: [ColorGradient(.blue, .purple)]
))
CardView(showShadow: true) {
Text("Time")
.padding([.leading, .top],10)
.font(.caption)
ChartLabel("10h 50m", type: .custom(size: 10, padding: EdgeInsets(top: 0.0, leading: 10.0, bottom: 0.0, trailing: 10.0), color: Color(UIColor.secondaryLabel)), format: "%0.1f")
BarChart()
.padding(.horizontal,10)
.padding(.bottom,5)
}
.data(demoData3)
.chartStyle(ChartStyle(backgroundColor: .white,
foregroundColor: [ColorGradient(.blue, .purple)]
))
}
.frame(width: .infinity, height: 150, alignment: .center)
}
}
}
@app4g that looks nice, you forked already ChartView but without changes, do you have plans to implement the above shown changes? Would be nice :)
@JakobStadlhuber I just made the changes locally and am just still playing around / testing it.
eg: it doesn't honour dark mode in cardview
and trying to get this to work. In the interim (screenshot) shows just changing it from .white
to .lightgray
jus to see if it works.
Yeah.. I've forked It but have yet to sync it. Possibly over the next few days as I play more w/ it.
Sounds good @app4g I will follow your repo. Do you think it is possible to get a y axis too?
@app4g some news with the forked repo?
Forked Repo : https://github.com/app4g/ChartView
Here is the Demo Project or rather the code I was working on to see /make the changes https://github.com/app4g/ChartViewV2-Demo-Project
v2 ticket
Ticket description:
I'm having trouble getting the legend and labels to show in the ChartGrid with a LineChart. I'm passing in the tuple for the data but only the data is displayed