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

Grouped columns misplaced #242

Closed
JanciP opened this issue Jul 24, 2015 · 34 comments
Closed

Grouped columns misplaced #242

JanciP opened this issue Jul 24, 2015 · 34 comments

Comments

@JanciP
Copy link

JanciP commented Jul 24, 2015

Hey, I'm having troubles with grouped bar chart.
My barChartData are following:

x-values (array of dates):
02.júla.15,
23.júla.15,
24.júla.15

dataSets:
ChartDataSet, label: tst, 1 entries:
ChartDataEntry, xIndex: 0, value 0.0,
ChartDataSet, label: tst, 1 entries:
ChartDataEntry, xIndex: 0, value 0.0,
ChartDataSet, label: tst, 1 entries:
ChartDataEntry, xIndex: 0, value 0.0,
ChartDataSet, label: tst, 1 entries:
ChartDataEntry, xIndex: 0, value 0.0,
ChartDataSet, label: tst, 1 entries:
ChartDataEntry, xIndex: 0, value 0.0,
ChartDataSet, label: tst, 1 entries:
ChartDataEntry, xIndex: 1, value 39.0,
ChartDataSet, label: tst, 1 entries:
ChartDataEntry, xIndex: 2, value 16.0,
ChartDataSet, label: tst, 1 entries:
ChartDataEntry, xIndex: 2, value 28.0

This produces almost correct result, however bars seems to have wrong position as showed in this image http://imgur.com/Vq43QFH

What am I doing wrong? :)

@JanciP
Copy link
Author

JanciP commented Jul 24, 2015

I've found out that adding another BarChartData for different x-cooridnate creates this Data for other indexes as well... that's why everything is moved by some offset, but I have not idea how fix it.

Data:
BarChartDataEntry *entry = [[BarChartDataEntry alloc] initWithValues:@[@1] xIndex:0];
BarChartDataEntry *entry2 = [[BarChartDataEntry alloc] initWithValues:@[@4] xIndex:0];

BarChartDataSet *set = [[BarChartDataSet alloc] initWithYVals:@[entry] label:@"tst"];
BarChartDataSet *set2 = [[BarChartDataSet alloc] initWithYVals:@[entry2] label:@"tst"];

BarChartDataEntry *entry4 = [[BarChartDataEntry alloc] initWithValues:@[@4] xIndex:2];
BarChartDataSet *set4 = [[BarChartDataSet alloc] initWithYVals:@[entry4] label:@"tst"];

NSArray *tstArr = @[set,set2, set4];

BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:tstArr];
self.chart.data = data;

Produces this (note the "highlighted column that shouldn't even exist for that index):
http://imgur.com/TlJuonl

@danielgindi
Copy link
Collaborator

Did you add the xIndexes?

@JanciP
Copy link
Author

JanciP commented Jul 26, 2015

Yes, there are 3 x-indexes (timestamps)
<__NSArrayM 0x7a897960>(
02.júla.15,
23.júla.15,
24.júla.15
)

@danielgindi
Copy link
Collaborator

You need to attach a screenshot or a working sample project

@JanciP
Copy link
Author

JanciP commented Jul 27, 2015

Ok, while using HorizontalBarChartView and using this array as a X-data:
xVals = <__NSArrayM 0x7a897960>(
02.júla.15,
23.júla.15,
24.júla.15
)

and this as a dataSets:
BarChartDataEntry *entry = [[BarChartDataEntry alloc] initWithValue:1 xIndex:0];
BarChartDataEntry *entry2 = [[BarChartDataEntry alloc] initWithValue:4 xIndex:0];
BarChartDataSet *set = [[BarChartDataSet alloc] initWithYVals:@[entry] label:@"test1"];
BarChartDataSet *set2 = [[BarChartDataSet alloc] initWithYVals:@[entry2] label:@"test2"];

BarChartDataEntry *entry3 = [[BarChartDataEntry alloc] initWithValues:@[@6] xIndex:1];
BarChartDataEntry *entry4 = [[BarChartDataEntry alloc] initWithValues:@[@7] xIndex:1];
BarChartDataSet *set3 = [[BarChartDataSet alloc] initWithYVals:@[entry3] label:@"test3"];
BarChartDataSet *set4 = [[BarChartDataSet alloc] initWithYVals:@[entry4] label:@"test4"];

NSArray *tstArr = @[set,set2,set3,set4];

BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:tstArr];
[data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];
data.groupSpace = 0.8;
self.chart.data = data;

Produces this graph, (note the "selected" gray column with value 1, which shouldn't exist for that index): http://imgur.com/Cmt0QtM

@danielgindi
Copy link
Collaborator

It seems to be a highlight bug, when the x axis is reversed.
Could you try with latest version (2.1.2)

@PhilJay did you notice this?

@JanciP
Copy link
Author

JanciP commented Jul 27, 2015

I updated the library, (changed x-values to array ("1","2","3"). Placement of bars is wrong, however now it doesn't repeat the values (I can only "highlight" 6 and 7 bars in "2" index as shown on screenshot - http://imgur.com/J2qEM47).

@liuxuan30
Copy link
Member

@danielgindi though I don't fully understand this issue, but it sounds like it is related to issue #214? I got a PR for it. BTW, I don't see the x axis is reversed?

@JanciP, if possible that you are familiar with the code, can you try if #221 fix your issue?

@JanciP
Copy link
Author

JanciP commented Jul 27, 2015

@liuxuan30 I'm not very familiar with the code, however I looked at your files and modified mine accordingly but the issue is still present. Bars are still drawn at wrong place.

I've tried adding datas for every x-value. This is what it looks like : with #221 implemented http://imgur.com/2bdCjsb

@danielgindi
Copy link
Collaborator

Try to invert the xaxis see if it still happens

On Mon, Jul 27, 2015 at 12:30 PM, JanciP notifications@github.com wrote:

@liuxuan30 https://github.com/liuxuan30 I'm not very familiar with the
code, however I looked at your files and modified mine accordingly but the
issue is still present. Bars are still drawn at wrong place.

I've tried adding datas for every x-value. This is what it looks like :
with #221 #221
implemented http://imgur.com/2bdCjsb


Reply to this email directly or view it on GitHub
#242 (comment)
.

@JanciP
Copy link
Author

JanciP commented Jul 27, 2015

@danielgindi you mean using barchart class instead of horizontal bar chart?

@danielgindi
Copy link
Collaborator

danielgindi commented Jul 27, 2015 via email

@JanciP
Copy link
Author

JanciP commented Jul 27, 2015

With leftAxis.inverted = YES; it still unfortunately happens :( (ChartYAxis *leftAxis = self.chart.leftAxis;)

@liuxuan30
Copy link
Member

@danielgindi I think I can confirm it is same issue as #214, only that I am dealing with bar chart, but this is horizontal bar chart, which I don't change yet. It is reproducible on bar chart and horizontal bar chart with same dataSets.

@JanciP do you change the horizontal bar chart code like mine, not in bar chart code? It should take effect. Anyway, I have pushed code for horizontal bar chart at #221 . Please try it. Make sure you change the correct file for horizontal bar chart.

After I apply my potential fix, I got the screenshot, it seems render and highlight OK, but I am guessing shouldn't the bars be center aligned in their x axis zone? I touched nothing about the alignment.
67

dataSet code:

- (void)setDataCount:(int)count range:(double)range
{
    NSMutableArray *xVals = [[NSMutableArray alloc] init];
    xVals = @[@"jan",@"feb",@"mar"];
    BarChartDataEntry *entry = [[BarChartDataEntry alloc] initWithValue:1 xIndex:0];
    BarChartDataEntry *entry2 = [[BarChartDataEntry alloc] initWithValue:4 xIndex:0];
    BarChartDataSet *set = [[BarChartDataSet alloc] initWithYVals:@[entry] label:@"test1"];
    BarChartDataSet *set2 = [[BarChartDataSet alloc] initWithYVals:@[entry2] label:@"test2"];

    BarChartDataEntry *entry3 = [[BarChartDataEntry alloc] initWithValues:@[@6] xIndex:1];
    BarChartDataEntry *entry4 = [[BarChartDataEntry alloc] initWithValues:@[@7] xIndex:1];
    BarChartDataSet *set3 = [[BarChartDataSet alloc] initWithYVals:@[entry3] label:@"test3"];
    BarChartDataSet *set4 = [[BarChartDataSet alloc] initWithYVals:@[entry4] label:@"test4"];

    NSArray *tstArr = @[set,set2,set3,set4];

    BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:tstArr];
    [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];

    _chartView.data = data;
}

@liuxuan30
Copy link
Member

Alright I figured out the alignment problem.

@JanciP, I am not sure if it is your issue or the ios-chart duty to handle, but if there are two bars in one group, there should be only two dataSets, not 4, and each dataSet has two dataEntries. What you are using has 4 dataSets, and it leads to more space left for each x axis zone, that's why it is not centered.

Try below code:

    NSMutableArray *xVals = [[NSMutableArray alloc] init];
    xVals = @[@"jan",@"feb", @"mar"];
    BarChartDataEntry *entry = [[BarChartDataEntry alloc] initWithValue:1 xIndex:0];
    BarChartDataEntry *entry2 = [[BarChartDataEntry alloc] initWithValue:4 xIndex:0];

    BarChartDataEntry *entry3 = [[BarChartDataEntry alloc] initWithValue:6 xIndex:1];
    BarChartDataEntry *entry4 = [[BarChartDataEntry alloc] initWithValue:7 xIndex:1];

    BarChartDataSet *set = [[BarChartDataSet alloc] initWithYVals:@[entry,entry3] label:@"test1"];
    BarChartDataSet *set2 = [[BarChartDataSet alloc] initWithYVals:@[entry2,entry4] label:@"test2"];
    //    BarChartDataSet *set3 = [[BarChartDataSet alloc] initWithYVals:@[entry3] label:@"test3"];
    //    BarChartDataSet *set4 = [[BarChartDataSet alloc] initWithYVals:@[entry4] label:@"test4"];

    NSArray *tstArr = @[set,set2];

    BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:tstArr];
    [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];

    _chartView.data = data;

Screen shot on my side based on #221
new67

@danielgindi
Copy link
Collaborator

danielgindi commented Jul 27, 2015 via email

@liuxuan30
Copy link
Member

about the alignment, I think it's @JanciP problem. but for the position, it's ours. I think I broke my PR by merging from upstream master... I will try figure a way later.

@danielgindi
Copy link
Collaborator

What do you mean by position? The new screenshot looks good

@liuxuan30
Copy link
Member

@danielgindi take a look at #214 , same issue for bar+horizontal bar chart. I got PR #221 for it.

It renders the bars at wrong position, if some xIndex don't have entries. To be exact, the xValsCount is not equal to entryCount in each dataSet. This will lead to wrong position.

Very simple to reproduce... just paste the above dataSet code to the chart demo, you will see wrong position and wrong highlight...

@danielgindi
Copy link
Collaborator

Well the code above looks good, with a valid screenshot. I think you are referring to the code in the other issue?

@liuxuan30
Copy link
Member

This is the test dataSet code I used before, it render at wrong position and highlight for second group is failed.

    NSMutableArray *xVals = [[NSMutableArray alloc] init];
    for (int i = 0; i < 11; i++)
    {
        [xVals addObject:[@(i + 2015) stringValue]];
    }
    NSMutableArray *yVals1 = [[NSMutableArray alloc] init];
    NSMutableArray *yVals2 = [[NSMutableArray alloc] init];

    for (int i = 0; i < 11; i++)
    {
        if (i == 0) {
            [yVals1 addObject:[[BarChartDataEntry alloc] initWithValue:2354235 xIndex:i]];
            [yVals2 addObject:[[BarChartDataEntry alloc] initWithValue:3354235 xIndex:i]];
        } else if (i == 10) {
            [yVals1 addObject:[[BarChartDataEntry alloc] initWithValue:6354235 xIndex:i]];
            [yVals2 addObject:[[BarChartDataEntry alloc] initWithValue:7354235 xIndex:i]];
        } else {
            continue;
        }
    }

    BarChartDataSet *set1 = [[BarChartDataSet alloc] initWithYVals:yVals1 label:@"Company A"];
    [set1 setColor:[UIColor colorWithRed:104/255.f green:241/255.f blue:175/255.f alpha:1.f]];
    BarChartDataSet *set2 = [[BarChartDataSet alloc] initWithYVals:yVals2 label:@"Company B"];
    [set2 setColor:[UIColor colorWithRed:164/255.f green:228/255.f blue:251/255.f alpha:1.f]];

    NSMutableArray *dataSets = [[NSMutableArray alloc] init];
    [dataSets addObject:set1];
    [dataSets addObject:set2];

    BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:dataSets];
    data.groupSpace = 0.8;
    [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];
    _chartView.leftAxis.startAtZeroEnabled = NO;
    _chartView.rightAxis.startAtZeroEnabled = NO;
    _chartView.data = data;

just replace it in multiple bar chart view controller.

@JanciP
Copy link
Author

JanciP commented Jul 27, 2015

@liuxuan30 agree, with your #221 code and advice you provided in last post, it seems to be working. Thank you!

@liuxuan30
Copy link
Member

@JanciP you are welcome!

@danielgindi
Below dataSet also can show the problem. I tested again if it is at xIndex 0 & 1 and leaves xIndex 2 without data, it just covered the true problem, so you don't see a problem, because 0 and 1 has all the data to draw. but if it has entries on 0 and 2 not at xIndex 1, it will render at a strange position.

NSMutableArray *xVals = [[NSMutableArray alloc] init];
    xVals = @[@"jan",@"feb", @"mar"];
    BarChartDataEntry *entry = [[BarChartDataEntry alloc] initWithValue:1 xIndex:0];
    BarChartDataEntry *entry2 = [[BarChartDataEntry alloc] initWithValue:4 xIndex:0];

    BarChartDataEntry *entry3 = [[BarChartDataEntry alloc] initWithValue:6 xIndex:2]; // not 1
    BarChartDataEntry *entry4 = [[BarChartDataEntry alloc] initWithValue:7 xIndex:2]; // not 1

    BarChartDataSet *set = [[BarChartDataSet alloc] initWithYVals:@[entry,entry3] label:@"test1"];
    BarChartDataSet *set2 = [[BarChartDataSet alloc] initWithYVals:@[entry2,entry4] label:@"test2"];
    //    BarChartDataSet *set3 = [[BarChartDataSet alloc] initWithYVals:@[entry3] label:@"test3"];
    //    BarChartDataSet *set4 = [[BarChartDataSet alloc] initWithYVals:@[entry4] label:@"test4"];

    NSArray *tstArr = @[set,set2];

    BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:tstArr];
    [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];

    _chartView.data = data;

@JanciP
Copy link
Author

JanciP commented Jul 27, 2015

@liuxuan30 based on your code I was able to display graph correctly. But is it also possible to have different number of DataEntries for each data set? Lets say for x:
1: 2 entries
2: 1 entry
3: 5 entries

@PhilJay
Copy link
Collaborator

PhilJay commented Jul 27, 2015

I will have to test this on Android, gimme a sec.

@PhilJay
Copy link
Collaborator

PhilJay commented Jul 27, 2015

Some words beforehand:

  • You need to have exactly as many BarDataSet objects as you want values per "same" x-index
  • Each dataset is not allowed to have more that 1 value per x-index

@PhilJay
Copy link
Collaborator

PhilJay commented Jul 27, 2015

I just tested on Android.

The following code:

        ArrayList<String> xVals = new ArrayList<String>();
        xVals.add("1st");
        xVals.add("2nd");
        xVals.add("3rd");
        xVals.add("4th");

        ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
        yVals1.add(new BarEntry(1f, 0));
        yVals1.add(new BarEntry(2f, 1));
        yVals1.add(new BarEntry(3f, 2));
        yVals1.add(new BarEntry(4f, 3));

        ArrayList<BarEntry> yVals2 = new ArrayList<BarEntry>();
        yVals2.add(new BarEntry(5f, 0));
        yVals2.add(new BarEntry(6f, 1));
        yVals2.add(new BarEntry(7f, 2));
        yVals2.add(new BarEntry(8f, 3));

        ArrayList<BarEntry> yVals3 = new ArrayList<BarEntry>();
        yVals3.add(new BarEntry(9f, 0));
        yVals3.add(new BarEntry(10f, 1));
        yVals3.add(new BarEntry(11f, 2));
        yVals3.add(new BarEntry(12f, 3));

        BarDataSet set1 = new BarDataSet(yVals1, "ds1");
        set1.setColor(Color.RED);
        BarDataSet set2 = new BarDataSet(yVals2, "ds2");
        set2.setColor(Color.BLUE);
        BarDataSet set3 = new BarDataSet(yVals3, "ds3");
        set3.setColor(Color.GREEN);

        ArrayList<BarDataSet> dataSets = new ArrayList<BarDataSet>();
        dataSets.add(set1);
        dataSets.add(set2);
        dataSets.add(set3);

        BarData data = new BarData(xVals, dataSets);
        mChart.setData(data);

Produced this result, which looks fine (and expected) to me.
device-2015-07-27-232932

BUT: As soon as you skip values (like the issue-opener does), problems arise that cause the bars to be on places where they don't belong. This is due to the reason that the bar positioning is not determined by the x-index span, but by the number of entries in the dataset, which is wrong.

@liuxuan30
Copy link
Member

@PhilJay I know little about Java+android, but based on the commit, looks like we share the same idea to fix. @danielgindi I am not sure If I missed anything somewhere. Please review

@JanciP
Copy link
Author

JanciP commented Jul 28, 2015

Ok so having same amount of objects(y-vals) for each BarDataSet works very well now (as proven by @PhilJay). My question is, would chart display correctly if we are tracking irregular occurences (that means that BarDataSets won't contain same amount of objects?

Code wise I mean something like this

        ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
        yVals1.add(new BarEntry(1f, 0));
        yVals1.add(new BarEntry(2f, 1));
        //no yval for x==2
        yVals1.add(new BarEntry(4f, 3));

        ArrayList<BarEntry> yVals2 = new ArrayList<BarEntry>();
        yVals2.add(new BarEntry(5f, 0));
        //no yvals for x== 1,2,3

        ArrayList<BarEntry> yVals3 = new ArrayList<BarEntry>();
        yVals3.add(new BarEntry(9f, 0));
        yVals3.add(new BarEntry(10f, 1));
        yVals3.add(new BarEntry(11f, 2));
        yVals3.add(new BarEntry(12f, 3));

@liuxuan30
Copy link
Member

can you try the code and give screenshot? I think it should work.

Make sure you have 3 dataSets
dataSet looks like:
dataSet 1: 0: 1, 1: 2, 3: 4
dataSet 2: 0: 5
dataSet 3: 0: 9, 1: 10, 2: 11, 3: 12

@JanciP
Copy link
Author

JanciP commented Jul 28, 2015

Irregular datas:

    NSMutableArray *xsVals = [[NSMutableArray alloc] init];
    xsVals = @[@"jan",@"feb", @"mar",@"apr"];
    BarChartDataEntry *entry0 = [[BarChartDataEntry alloc] initWithValue:1 xIndex:0];
    BarChartDataEntry *entry1 = [[BarChartDataEntry alloc] initWithValue:6 xIndex:1];
    BarChartDataEntry *entry3 = [[BarChartDataEntry alloc] initWithValue:2 xIndex:3];


    BarChartDataEntry *entry00 = [[BarChartDataEntry alloc] initWithValue:4 xIndex:0];

    BarChartDataEntry *entry000 = [[BarChartDataEntry alloc] initWithValue:5 xIndex:0];
    BarChartDataEntry *entry111 = [[BarChartDataEntry alloc] initWithValue:6 xIndex:1];
    BarChartDataEntry *entry222 = [[BarChartDataEntry alloc] initWithValue:4 xIndex:2];
    BarChartDataEntry *entry333 = [[BarChartDataEntry alloc] initWithValue:3 xIndex:3];

    BarChartDataSet *set = [[BarChartDataSet alloc] initWithYVals:@[entry0,entry1,entry3] label:@"test1"];
    BarChartDataSet *set2 = [[BarChartDataSet alloc] initWithYVals:@[entry00] label:@"test2"];
    BarChartDataSet *set3 = [[BarChartDataSet alloc] initWithYVals:@[entry000,entry111,entry222,entry333] label:@"test2"];

    NSArray *tstArr = @[set,set2,set3];


    BarChartData *data = [[BarChartData alloc] initWithXVals:xsVals dataSets:tstArr];

Produce this result (gaps in graph).
graph
I guess that this is probably expected result, but is it possible for graph to adjust to those gaps? From real life it would be like running sessions for each day - some days I'll run 3 times, some days I'll run once, or not at all.

@liuxuan30
Copy link
Member

Current scheme does not support this. the distance on xAxis is equal. If you are asking making the xAxis not equal distance, It sounds like what you are asking is like #176 and #194.

For the case you mentioned, I think current bar chart is more meaningful, if we squash all the gaps there, it seems not very easy to understand as bar chart. Bar chart has the nature to let people compare among the bars.

@JanciP
Copy link
Author

JanciP commented Jul 28, 2015

Ok @liuxuan30 I undestand, thank you very much for your help. I learned a lot from your posts. Thanks!

@JanciP JanciP closed this as completed Jul 28, 2015
danielgindi added a commit that referenced this issue Jul 30, 2015
Fixes bar charts x-index calculations (Fixes #214 and fixes #242)

Specifically when yValues are missing
@josman185
Copy link

Hello everybody. I have a question. Prior to my project update I was presenting my charts in a correct position:
img_0147

But after update to the last version Charts (3.0.2) I'm getting my chart in wrong position:
img_0146

Does somebody knows why this happens?. Thanks in advance.

regas99 pushed a commit to regas99/MPAndroidChart that referenced this issue Apr 1, 2019
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

5 participants