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

Charts 3.0 unable to draw discontinuous line chart #1866

Closed
edalford11 opened this issue Nov 21, 2016 · 25 comments
Closed

Charts 3.0 unable to draw discontinuous line chart #1866

edalford11 opened this issue Nov 21, 2016 · 25 comments

Comments

@edalford11
Copy link

I need to be able to draw an incomplete chart. That is, a complete x axis but a half complete y axis.

In previous versions, I would just have to add the labels to the x axis, which would render a full x axis.

Then I would need to add the half complete y values to the chart, then the chart would render the half complete y values but still the full x axis. I don't see a way to do this in 3.0 since using a nil value in place of y is not allowed as it is expecting a double value:

for (int i = 0; i < pricesArray.count; i++){
  double price = pricesArray[i][@"price"];
  [chartValues addObject:[[ChartDataEntry alloc] initWithX:i y:price]];
}

I need to add an x data point with a nil y value. Please advise.

@lightwindy
Copy link

I have this problem, too.

@CAPIStkidd
Copy link
Contributor

CAPIStkidd commented Nov 23, 2016

This is a side effect of how the library changed how it does labeling.

The workaround for now is to make a second dataset with blank entries (so if you're wanting 100 entries and only 75 are drawn, make a second dataset with 25 entries, numbered 75-99) and add it as well.

@edalford11
Copy link
Author

@CAPIStkidd how do I make blank entries? Creating ChartDataEntry looks like it forces you to give it a double value, which does draw an incomplete chart the way I want it to but it messes with the scale of the y axis if I for example give the blank entries all 0 values.

@liuxuan30
Copy link
Member

liuxuan30 commented Nov 29, 2016

@edalford11 you can use multiple data sets to simulate the breaking lines. In Chart 3.0, you can specify the x values directly, not index any more, so it should be fine.
I used to implement line breaking in Chart 2.x, however in Chart 3.0, I am thinking using multiple data sets is better?

@edalford11
Copy link
Author

@liuxuan30 I think you misinterpreted my last question. Using multiple data sets does work for breaking lines, but it messes with the scale of the y axis because the library forces you to put in a numeric value for the y values, which messes up the chart as a whole. If ChartDataEntry allowed you to put in EMPTY y values, then this approach would work. As I see it right now, the 3.0 version has disallowed line breaking charts because of this.

@Onoppe
Copy link

Onoppe commented Nov 29, 2016

I have the same issue here. Don't know why this issue is closed.

@liuxuan30 liuxuan30 reopened this Nov 30, 2016
@liuxuan30
Copy link
Member

liuxuan30 commented Nov 30, 2016

@edalford11 are you saying 2.x version can support line breaking by using multiple data sets? I didn't try it yet, but from my understanding, all the data sets share the same x axis and y axis, so the xMin, xMax, yMin, yMax should not be impacted or messed up.

Let's say I want to break one line (1,1) -> (10,10) into two like: (1,1) -> (2,5), (3,6) -> (10,10)
So data set A:(1,1),(2,5); and data set B: (3,6), (10,10). Chart 3.0 should handle this two sets and draw lines respectively in x axis roughly [1,6], y axis [1,10]. I don't see it messes any y axis scale or min/max value.

Am I misunderstanding anything, or your discontinuous line chart is not what I meant 'breaking lines'?

@lightwindy
Copy link

lightwindy commented Nov 30, 2016

The discontinuous line chart we meant is not 'breaking lines'. It means there are some data have x-axis values , but the y-axis values are nil. We can do that in Charts 2.0. but can't do that in Charts 3.0.
For example, there are 12 months in the x-axis, only 2 of them have y-axis value, others is nil. I want to draw a 12-month chart, not a 2-month chart. How to do it ?

@liuxuan30
Copy link
Member

liuxuan30 commented Nov 30, 2016

@lightwindy maybe it's different terms, but from what you said, they are the same - #280

How did you do it in Chart 2.0? Overriding line chart renderer or multiple data sets? As I said above, we could use two data sets to simulate the gap between two lines. It's complicated I admit. Overrding the line chart renderer is harder, but also flexible.

In chart 3.0, yes, now every entry takes x and y, which means jumping is not possible for now.

@lightwindy
Copy link

lightwindy commented Nov 30, 2016

In Charts 2.0, we can give the x-axis value and y-axis value respectively. Firstly, we can give the x-axis value and formatted them. Then give the y-axis value contain (y-value & x-index).
See following:

  1. xVals.append(Formatted Data)
  2. yVals.append(ChartDataEntry(value: Double, xIndex: Int))
  3. LineChartDataSet(yVals: yVals)
  4. LineChartData(xVals: xVals, dataSets: dataSets)

@edalford11
Copy link
Author

edalford11 commented Nov 30, 2016

@liuxuan30 Let's say you have a LineChartDataSet, which is the set you want to be visible on the chart. The solution you suggested is to create a second LineChartDataSet, which will serve as the invisible line set that makes the line chart look discontinuous. This works but the problem is let's say the first LineChartDataSet has a y value range of 300 to 400. We are forced to give the second LineChartDataSet y values. If we give it say all 0's, the range of the y axis now becomes 0-400, which DOES screw up the scale of the y axis and the chart ends up drawing in a very non granular way. The second LineChartDataSet needs to have EMPTY y values such that the chart does not change the scale based on those y values. This was easily done in 2.0.

My temporary solution is to make sure the invisible LineChartDataSet has y values that are somewhere in the middle of the range of the first LineChartDataSet and set lineWidth to 0 so it doesn't draw, which keeps the scale of the y axis normal. Event though this works, it's not an ideal solution so I'd imagine we'd want to get back to more of the solution that 2.0 had for discontinuous line charts.

@liuxuan30
Copy link
Member

@edalford11 I think you misunderstood.
What I mentioned is that, every data set you created is visible;
say we have two lines, which is discontinuous:
The first line is connecting (0,1) to (2,3)
The second line is connecting (4,4) to (7, 6).

As you can see, (2,3) and (4,4) have gap.

Here's an example:
dl
I just set different x value for set 1 and set 2:

    for (int i = 0; i < count; i++)
    {
        if (i < count / 2) {
            double val = arc4random_uniform(range) + 3;
            [values addObject:[[ChartDataEntry alloc] initWithX:i y:val]];
        } else {
            double val = arc4random_uniform(range) + 3;
            [values2 addObject:[[ChartDataEntry alloc] initWithX:i+5 y:val]];
        }
    }

I did a dirty trick to make a gap by +5 (after the first gap, there is no more gap since the dot is connected).
This two-set trick make a discontinuous line had one defect: the x animation, so if you need x animation, it will have two lines draws simultaneously.

I used to override the line chart renderer to support this feature in Chart 2.0, however, it has pains while considering filling the rect. I think it's a better solution, but also a tough feature to implement.

@liuxuan30
Copy link
Member

liuxuan30 commented Dec 5, 2016

You can take a look at #280, that's where we used to talk about this. Someone filed a PR, however for some reason it is closed by the author.
@danielgindi suggested to use the multiple data sets way to do it. But I guess he forgot the x animation.
Still, I guess it's a great feature to have by not using multiple data sets

@liuxuan30
Copy link
Member

About the x animation, I just come up with a quick fix: override the animator, to draw the data sets sequentially.

@edalford11
Copy link
Author

@liuxuan30 that makes sense but what I'm trying to do is not have the trailing data visible so this trick doesn't really work. In your example, the second data set needs to be completely invisible while keeping the same length of the x axis, which is why I'm saying we need the ability to add y values such that the y axis ignores the values when scaling.

@liuxuan30
Copy link
Member

liuxuan30 commented Dec 6, 2016

I am kind of lost here.. You don't want the second line visible but keep the x axis the same min/max? It looks not like discontinuous lines..

Why not just set axis max value to be a large value, like 2x of your entry max value? So you have a plenty of space after your line?

A screenshot may help me understand.

@edalford11
Copy link
Author

The x axis labels are made up of timestamps. It's a stock chart, which shows the x axis from market open (9:30am) to market close (4:00pm). The y values extend along the x axis as the day goes on. Thus the line won't complete on the chart until 4:00pm.

I think you understand exactly how the chart is to be built at this point. You mentioned setting a max value on the x axis. Can you please explain how you do that? We are forced to make ChartDataEntry objects in order to build the x and y axis. I don't see how the chart would be smart enough to show this kind of chart by just setting a max value on the x axis.

@liuxuan30
Copy link
Member

liuxuan30 commented Dec 19, 2016

'stock chart' do explain what you need. What I would try is this:
1 set xAxis max is like 4:00 pm value
2 add entries like I did above, e.g.

    _chartView.xAxis.axisMaximum = 8;
    for (int i = 0; i < 8; i++)
    {
        if (i < 8 / 2) {
            double val = arc4random_uniform(range) + 3;
            [values addObject:[[ChartDataEntry alloc] initWithX:i y:val]];
        }
    }

I just make a quick tweak in ChartsDemo, it looks like (it has a slow animation, which I don't know why yet):
image

Can this solve your problem?

The idea will be when you get new data you just update or create a new data and set it again, so it will 'grow' until 4:00pm

@edalford11
Copy link
Author

Your example you are setting axis labels to numbers. I don't see how this would work when the x axis labels are string values. axisMaximum only accepts double values anyway.

@liuxuan30
Copy link
Member

liuxuan30 commented Dec 27, 2016

it's just a showcase how to get the visual effect for 'discontinuous line'. Since x is double and we uses valueFormatter, we can map [xMin, xMax] to [9:00am, 4:00pm] right? Formatting is another topic

@jjatie jjatie closed this as completed Apr 1, 2018
@jitccgcg
Copy link

Has anything changed since this thread was closed? Does the newest version of Charts support gaps in a dataset?

@JCMcLovin
Copy link
Contributor

@edalford11 Eric, did you ever figure out how to do this?

@edalford11
Copy link
Author

edalford11 commented Jun 13, 2018

@JCMcLovin I was able to achieve this by creating 2 separate LineChartDataSet objects.

LineChartDataSet *set1 = [[LineChartDataSet alloc] initWithValues:chartValues label:@"Price"];
LineChartDataSet *set2 = [[LineChartDataSet alloc] initWithValues:emptyChartValues label:nil];

Where chartValues and emptyChartValues are arrays of ChartDataEntry objects. When adding both sets to an an array named dataSets (order matters for which dataset gets displayed first), they can be added to the chart like so.

LineChartData *data = [[LineChartData alloc] initWithDataSets:dataSets];

This displays a discontinuous chart the way I wanted.

I know I know obj-c gross.

@JCMcLovin
Copy link
Contributor

@edalford11 Thanks, Eric. I guess I'll have to give that a try.

Also, 👍 on this:

I know I know obj-c gross.

@basabendra
Copy link

Hi. I hope my message finds all of you well amid this global crisis.

I am using latest version of chart library to plot a line chart.

My graph shows months till Feb21. I don't want to show 'zero' values for all future months. It should be blank. Thats what I want to achieve.

I would need little guidance on how to make it.

Screen Shot 2020-04-02 at 9 41 51 AM

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

9 participants