You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a LineChartView that I am applying a custom XAxisRenderer to draw on top of the chart to. I am having issues with the drawn labels shifting around when I am scrolling: Link to imgur vid like so. It seems to appear once the data point leaves the viewPortHandler that it shifts the labels, but I am unsure what to do to fix this. Using Charts 3.0.5, Swift 4.
func updateHourlyData(){HourlyLineChart.clear()
lineChartEntries.removeAll()
hourlyTimes.removeAll()
hourlyTemperaturesStr.removeAll()
hourlyPrecip.removeAll()
hourlyIcons.removeAll()
if selectedLocationData?.hourlyFcst?.hourly !=nil{
for index in (selectedLocationData?.hourlyFcst?.hourly)! {
hourlyTimes.append(index.time!)
hourlyTemperaturesStr.append((index.temperature?.getValue())!)
hourlyIcons.append(UIImage(named:"\(index.iconCode!)_main")!)
hourlyPrecip.append(index.precip!)}}
if selectedLocationData?.hourlyFcst?.hourly !=nil && hourlyTimes.count >0{
hourlyGraphHeight.constant =250// Populate chartDataEntries
for index in hourlyTimes.indices {letxVal=Double(index).rounded()varyVal=Double(index)letyValStr=hourlyTemperaturesStr[index]
if !yValStr.isEmpty {
yVal =Double(yValStr)!
}
lineChartEntries.append(ChartDataEntry(x: xVal, y: yVal, data: selectedLocationData?.hourlyFcst?.hourly![index]))}// Set up a dataset for data model
dataSet.values = lineChartEntries
// Setup a valueformatter to get rid of decimals in the graphletformat=NumberFormatter()
format.numberStyle =.none
letformatter=HourTempFormatter(numberFormatter: format)
dataSet.valueFormatter = formatter
// Set the data using the above dataSet for the chartletdata=LineChartData(dataSet: dataSet)
data.setDrawValues(true)
data.setValueTextColor(UIColor(hex:"fafafa"))HourlyLineChart.data = data
// Custom renederers for icons, precipitationletcustomXAxisRenderer=XAxisCustomRenderer(viewPortHandler:HourlyLineChart.viewPortHandler, xAxis:HourlyLineChart.xAxis, transformer:HourlyLineChart.getTransformer(forAxis:YAxis.AxisDependency.left), icons: hourlyIcons, precipitationArray: hourlyPrecip)HourlyLineChart.xAxisRenderer = customXAxisRenderer
// Custom renderer for timeHourlyLineChart.xAxis.valueFormatter =IndexAxisValueFormatter(values: hourlyTimes)// Backup renderer for times (CHARTS 3.0.4 -> 3.0.5) ISSUE//HourlyLineChart.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in// return self.hourlyTimes[Int(index)]//})}// ELSE BLOCK TO COLLAPSE CHART IF NO DATA//else {// hourlyGraphHeight.constant = 0// }HourlyLineChart.notifyDataSetChanged()}
And here is the custom xAxisRenderer:
publicclassXAxisCustomRenderer:XAxisRenderer{// Dict to hold the weather icons arrayprivatevaricons:[UIImage]// Dict to hold the preciptation mappingprivatevarprecipitationArray:[String]// Array to hold the time string//private var timesArray: [String]init(viewPortHandler:ViewPortHandler, xAxis:XAxis, transformer:Transformer, icons:[UIImage], precipitationArray:[String]){self.icons = icons
self.precipitationArray = precipitationArray
//self.timesArray = times
super.init(viewPortHandler: viewPortHandler, xAxis: xAxis, transformer: transformer)}overridepublicfunc drawLabels(context:CGContext, pos:CGFloat, anchor:CGPoint){
guard
let xAxis =self.axis as?XAxis,let transformer =self.transformer
else{return}#if os(OSX)letparaStyle=NSParagraphStyle.default.mutableCopy()as!NSMutableParagraphStyle#elseletparaStyle=NSParagraphStyle.default.mutableCopy()as!NSMutableParagraphStyle#endif
paraStyle.alignment =.center
letlabelAttrs:[NSAttributedStringKey:Any]=[NSAttributedStringKey.font: xAxis.labelFont,NSAttributedStringKey.foregroundColor: xAxis.labelTextColor,NSAttributedStringKey.paragraphStyle: paraStyle]letFDEG2RAD=CGFloat(Double.pi / 180.0)letlabelRotationAngleRadians= xAxis.labelRotationAngle * FDEG2RAD
letcenteringEnabled= xAxis.isCenterAxisLabelsEnabled
letvalueToPixelMatrix= transformer.valueToPixelMatrix
varposition=CGPoint(x: 0.0, y: 0.0)varlabelMaxSize=CGSize()
if xAxis.isWordWrapEnabled
{
labelMaxSize.width = xAxis.wordWrapWidthPercent * valueToPixelMatrix.a
}letentries= xAxis.entries
for i in stride(from:0, to: entries.count, by:1){
if centeringEnabled
{
position.x =CGFloat(xAxis.centeredEntries[i])}else{
position.x =CGFloat(entries[i])}
position.y = 0.0
position = position.applying(valueToPixelMatrix)
if viewPortHandler.isInBoundsX(position.x){letlabel= xAxis.valueFormatter?.stringForValue(xAxis.entries[i], axis: xAxis)??""letlabelns= label asNSString
if xAxis.isAvoidFirstLastClippingEnabled
{// avoid clipping of the last
if i == xAxis.entryCount -1 && xAxis.entryCount >1{letwidth= labelns.boundingRect(with: labelMaxSize, options:.usesLineFragmentOrigin, attributes: labelAttrs, context:nil).size.width
if width >(viewPortHandler.offsetRight)* 2.0
&& position.x + width > viewPortHandler.chartWidth
{
position.x -= width / 2.0
}}else if i ==0{// avoid clipping of the firstletwidth= labelns.boundingRect(with: labelMaxSize, options:.usesLineFragmentOrigin, attributes: labelAttrs, context:nil).size.width
position.x += width / 2.0
}}letrawIcon:UIImage=icons[Int(entries[i])].fixedOrientation().imageRotatedByDegrees(degrees:180)leticon:CGImage= rawIcon.cgImage!
// Draw the time labelsdrawLabel(
context: context,
formattedLabel: label,
x: position.x,
y: pos +33,
attributes: labelAttrs,
constrainedToSize: labelMaxSize,
anchor: anchor,
angleRadians: labelRotationAngleRadians)// let time = timesArray[Int(i)]//drawLabel(context: context, formattedLabel: time, x: position.x + 8, y: viewPortHandler.chartHeight - 2, attributes: labelAttrs, constrainedToSize: labelMaxSize, anchor: anchor, angleRadians: labelRotationAngleRadians)// Draw the icons
context.draw(icon, in:CGRect(x: position.x -15, y: viewPortHandler.chartHeight -47, width:CGFloat(30), height:CGFloat(27)))// Draw the precipitation valueletprecip=precipitationArray[Int(i)]//if( !(precip.starts(with: "0"))) {// Draw the precip stringdrawLabel(context: context, formattedLabel: precip, x: position.x +8, y: viewPortHandler.chartHeight -2, attributes: labelAttrs, constrainedToSize: labelMaxSize, anchor: anchor, angleRadians: labelRotationAngleRadians)// Draw the precip imageletprecipitationIcon:CGImage=(UIImage(named:"rainCloud")?.fixedOrientation().imageRotatedByDegrees(degrees:180).cgImage)!
context.draw(precipitationIcon, in:CGRect(x: position.x -19, y: viewPortHandler.chartHeight -15, width:15, height:15))letaxisLine:CGImage=(UIImage(named:"axisLine")?.cgImage)!
// Draw top axis
context.draw(axisLine,in:CGRect(x:-20, y:0, width: viewPortHandler.chartWidth +50, height:50))//let arrowIconRight: CGImage = (UIImage(named: "arrow")?.fixedOrientation().imageRotatedByDegrees(degrees: 180).alpha(alpha: 0.2)!.cgImage)!//let arrowIconLeft: CGImage = (UIImage(named: "arrow")?.fixedOrientation().imageRotatedByDegrees(degrees: 0).alpha(alpha: 0.2)!.cgImage)!//context.draw(arrowIconRight, in: CGRect(x: viewPortHandler.chartWidth - 30 , y: viewPortHandler.chartHeight/2.5, width: 15, height: 15))//context.draw(arrowIconLeft, in: CGRect(x: 10 , y: viewPortHandler.chartHeight/2.5, width: 15, height: 15))// Draw bottom axis
context.draw(axisLine,in:CGRect(x:-20, y: viewPortHandler.chartHeight -80, width: viewPortHandler.chartWidth +50, height:50))}}}}
The text was updated successfully, but these errors were encountered:
I have a LineChartView that I am applying a custom XAxisRenderer to draw on top of the chart to. I am having issues with the drawn labels shifting around when I am scrolling: Link to imgur vid like so. It seems to appear once the data point leaves the viewPortHandler that it shifts the labels, but I am unsure what to do to fix this. Using Charts 3.0.5, Swift 4.
Here is the code to setup the LineChartView
Here is the code that updates data
And here is the custom xAxisRenderer:
The text was updated successfully, but these errors were encountered: