Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bar width #2410

Closed
zykis opened this issue May 3, 2017 · 22 comments
Closed

Bar width #2410

zykis opened this issue May 3, 2017 · 22 comments

Comments

@zykis
Copy link

zykis commented May 3, 2017

Any way i can force bar width to be wider?
screen shot 2017-05-03 at 23 08 03

Yet, dataset with 1 entity works pretty well:
screen shot 2017-05-03 at 23 36 14

@hernanarber
Copy link

hernanarber commented May 4, 2017

Hi @zykis:

First of All Set your barWidth for the BarChartDataSet:

chartData.barWidth = defaultbarwidth // I Put is as 0.4

Then what you can do is make an Outlet for the Width of the Chart Constraint like this:
(Drag from Storyboard)
@IBOutlet weak var layoutBarChartWidth: NSLayoutConstraint!

Then you can Set the Width of the Chart According to the Amount of Data you have

            let dataBars = <YOUR DATA OBJECTS>
            let realBarWidth = 20.0
            // Chart Width:
            let fullWidth = CGFloat(realBarWidth*Double(dataBars.count))
            layoutBarChartWidth.constant = max(fullWidth, view.frame.size.width)

Hope this Helps :-)

@zykis
Copy link
Author

zykis commented May 4, 2017

Thanks, @hernanarber !
I'll try it this evening, but still got some quesitons:

  1. I can't find barWidth property in BarChartDataSet class. Even inspecting IBarChartDataSet.swift file shows only "barBorderWidth", "barBorderColor" etc. May be it was removed from new API?
  2. I did declare IBOutlets of different UI objects in my Storyboard, but as for NSLayoutConstraint. How it can be actually ctrl-dragged from Storyboard, if it's not an UIView inheritor? I mean, if i ctrl-drag any point of BarChartView, IB will suggest me to create BarChartView outlet only

@hernanarber
Copy link

The .barWidth Property is not part of the ChartDataSet, but of the BarChartData :-)
let chartData = BarChartData(dataSet: chartDataSet)
Try it

@hernanarber
Copy link

For the constraint Go to the EXPLORER in the Storyboard so you can Ctrl+Drag the Constraint

@zykis
Copy link
Author

zykis commented May 4, 2017

@hernanarber oh, man!
Thank you a lot!!
I'll try this solution today

@zykis zykis closed this as completed May 4, 2017
@zykis zykis reopened this May 4, 2017
@aelam
Copy link
Contributor

aelam commented May 4, 2017

setting the visible range is what you want
checkout the BarLineChartViewBase.swift

     open func setVisibleXRange(minXRange: Double, maxXRange: Double)

@zykis
Copy link
Author

zykis commented May 4, 2017

@aelam Oh, thanks! I'll try that.
Though this method internally evaluating minScale and maxScale for viewportHandler.
I think the best way to handle this behavior is to understand, where these values (barWidth) are evaluating.

@hernanarber
Copy link

@aelam Can you explain me more about this?

I think this is what we need....

Thanks :-)

@zykis
Copy link
Author

zykis commented May 4, 2017

@hernanarber

  /// Limits the maximum and minimum value count that can be visible by pinching and zooming.
   ///
   /// e.g. minRange=10, maxRange=100 no less than 10 values and no more that 100 values can be viewed
   /// at once without scrolling.
   ///
   /// If you call this method, chart must have data or it has no effect.
   open func setVisibleXRange(minXRange: Double, maxXRange: Double)
   {
       let minScale = _xAxis.axisRange / maxXRange
       let maxScale = _xAxis.axisRange / minXRange
       _viewPortHandler.setMinMaxScaleX(
           minScaleX: CGFloat(minScale),
           maxScaleX: CGFloat(maxScale))
   }

That's what source tells us

@liuxuan30
Copy link
Member

liuxuan30 commented May 5, 2017

can be closed now

@zykis
Copy link
Author

zykis commented May 5, 2017

Well, BarChartData.barWidth not helps here.
Manipulations with setXVisibleRange can't change situation neither. I believe, it's connected with huge timestamps x-values. Any idea, where it's calculated in sources?
Timestamps are used since 1970

@liuxuan30
Copy link
Member

liuxuan30 commented May 5, 2017

Played with ChartsDemo, it's working:

        BarChartData *data = [[BarChartData alloc] initWithDataSets:dataSets];
        [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];
        
        data.barWidth = 1.0f;
        
        _chartView.data = data;

image

@zykis
Copy link
Author

zykis commented May 5, 2017

You have a full-width entity just because your X-axis width is equal to 1.0. Just a coincidence.
The thing is ChartBarData.barWidth is POINT-BASED value, where X-axis width = [dataSet xMax] - [dataSet xMin]. You can test it out by setting entities values with e1(x=0, y=1) and e2(x=1000,y=0.7) and barWidth = 1;

@aelam
Copy link
Contributor

aelam commented May 6, 2017 via email

@aelam
Copy link
Contributor

aelam commented May 6, 2017 via email

@hernanarber
Copy link

I Tried Setting the Visible Range:
barChartView.setVisibleXRange(minXRange: 0.0, maxXRange: 5.0)

But as a Result the BarWidth is Changing depending on the amount of bars, What I Wanted was a CONSTANT Bar Width regardless of how much data was on the Chart :-(

@zykis
Copy link
Author

zykis commented May 10, 2017

@aelam
Well, actually the bar width is not in PERCENTAGES, but in POINTS.
BarChartRenderer.swift:71 prepareBuffer()

let barWidthHalf = barData.barWidth / 2.0
let left = CGFloat(x - barWidthHalf)
let right = CGFloat(x + barWidthHalf)
barRect.origin.x = left
barRect.size.width = right - left
barRect.origin.y = top
barRect.size.height = bottom - top

CGRect is sizing elements in points, not in percentages. So it's just a misleading.

But since renderer calculating left and right as mentioned above, now i have first and last bars cutted half:
screenshot_20170510_161407
Guess, i need to dig into viewport offsets and set them equal or more, then the half of the bar width

@billylo1
Copy link

billylo1 commented Aug 2, 2017

I ran into the exact same issue with first/last bar cutted in half and barWidth problems (I also have timeIntervalSince1970 as xValues.)

Eventually got what my desired effect by storing # of days since the first bar as xValues; and use my custom formatter to translate xValue back to a String.

Hope this helps.

image

image

@aelam
Copy link
Contributor

aelam commented Aug 7, 2017

@zykis set the xAxisMin to -0.5 if you current minXValue is 0, then it wouldn't be cut, same as maxValue
and the unit of these -0.5, 0 , 0.5 are based on point not pixel, I said percentage before. But now I think you know what I mean now.

@aelam
Copy link
Contributor

aelam commented Aug 7, 2017

@zykis maybe you can try to keep every POINT in same pixels each time, then you can have a constant result that's what I meant

@zykis
Copy link
Author

zykis commented Aug 7, 2017

@billylo1 That's a nice point. I need to cut off some decades from my start value for sure :D
double ti = [date timeIntervalSince1970];
@aelam It worked fine for me. But i can't remember, when this solution was broken and by what circumstances.
My final solution fixed problem, by manipulating values of the bar:

BarChartData* data = [[BarChartData alloc] initWithDataSet:dataSet];

double xMin = [dataSet xMin]; // seconds since 1970x
double xMax = [dataSet xMax]; // seconds since 1970 + few days
double w = MAX(1, xMax - xMin); // if we have 7 days in xaxis, then its 7 * 24 * 60 * 60
double spacing = 0.05; // 5% of barWidth
double barWidth = w / [dataSet values].count - (spacing * w / ([dataSet values].count + 1)); // actual bar width
data.barWidth = barWidth;
[_chartView setFitBars:YES];

xaxis.spaceMin = barWidth / 10.0;
xaxis.spaceMax = barWidth / 10
xaxis.xOffset = barWidth;

_chartView.data = data;

screenshot_20170807_103654

@sshivanshu992
Copy link

sshivanshu992 commented Jul 12, 2023

I am not able to add the fixed the barWidth of while using the groupBars & groupWidth.

barChartData.barWidth = groupBarSpace.barWidth

let interval = barChartData.groupWidth(groupSpace: groupBarSpace.groupSpace, barSpace: groupBarSpace.barSpace)

let axisMaximum: Double = 0.0 + interval * groupBarSpace.groupCount

print("Interval per group: ", interval)
print("Group space : ", axisMaximum)

barChartData.groupBars(fromX: 0.0, groupSpace: groupBarSpace.groupSpace, barSpace: groupBarSpace.barSpace)

  • returning the groupSpace .....
    return (groupSpace: 0.36, barSpace: 0.02, barWidth: 0.3, groupCount: Double(labelsCount))

When only one entry in bar.
Screenshot 2023-07-13 at 01 39 19
When more than one entry in the bar.
Screenshot 2023-07-13 at 01 51 47

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants