boris-em / bemsimplelinegraph Goto Github PK
View Code? Open in Web Editor NEWElegant Line Graphs for iOS. (Charting library)
License: MIT License
Elegant Line Graphs for iOS. (Charting library)
License: MIT License
This thing is amazing!!! But one bug that I found so far: Everything works perfectly except for the time when all the data points have the same value. Then it gives this error:
'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [0 nan]'
With your help, I was able to add the marks for min and max. Thanks again for that.
Now I want to make the difference between the two lines bigger.
The chart should start at about the middle of the screenshot - the max line should stay.
Can you give me a hint, what and how to change the code to get this result?
This post is after testing the lowerGraph implementation in one of the fork.
Showing two graphs is working fine for me. But the same is not making sense when the scale for two graphs are different. The maxValue and minValue of two graphs need not be same (I believe the y axis scale is divided based on minValue and maxValue for each graph)
Problem : In my project where I am showing total sale on each day on main graph ( Y = sale in $ X= days in month) and sale of particular product 'A' on lower graph. 25000 in lower graph is plotted much higher than the 45000 in main graph. ( total sale always greater than sale of a particular product hence the maxValue and minValue for each graph is different)
currentlyCloser = pow((self.frame.size.width/(numberOfPoints-1))/2, 2);
currentlyCloser is declared as NSInteger:
NSInteger currentlyCloser;
- (BEMCircle *)closestDotFromtouchInputLine:(UIView *)touchInputLine
method returns nil if there are more points, change it to CGFloat to fix this:
CGFloat currentlyCloser = pow((self.frame.size.width/(numberOfPoints-1))/2, 2);
Hi Boris,
Thank you for writing this control, I have found it great to work with. My only issue (and it's not one that I can't work around) is that when I have several graphs in the same view-controller, the data source and delegate methods lack a sender id, making it a bit hack-ish to present different datasets for the graphs. Do you think it could be a good idea to add it?
Something like this:
- (int)numberOfPointsInGraph:(id)sender {
if ([sender isEqual:@"FirstGraph"]) {
return (int)[self.ArrayOfFirstValues count];
} else {
return (int)[self.ArrayOfOtherValues count];
}
}
Cheers,
Nils
Hello! Do not tell me how to make a height chart in the entire height UIView?
I love this chart but since I want to place this on a horizontal scrolling UIScrollView I can't use the touch feature to display the labels, since that disables the scrolling. I would like an option to display the points and value labels all the time instead on only on touch.
The demo app included in the project crashes at launch. I guess it's something related to the Storyboard. Here's the crash log:
*** First throw call stack:
(
0 CoreFoundation 0x0180a1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x015898e5 objc_exception_throw + 44
2 UIKit 0x007ad400 -[UIStoryboard name] + 0
3 UIKit 0x00249692 -[UIApplication _loadMainStoryboardFileNamed:bundle:] + 53
4 UIKit 0x00249949 -[UIApplication _loadMainInterfaceFile] + 245
5 UIKit 0x0024854e -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 543
6 UIKit 0x0025cf92 -[UIApplication handleEvent:withNewEvent:] + 3517
7 UIKit 0x0025d555 -[UIApplication sendEvent:] + 85
8 UIKit 0x0024a250 _UIApplicationHandleEvent + 683
9 GraphicsServices 0x037fff02 _PurpleEventCallback + 776
10 GraphicsServices 0x037ffa0d PurpleEventCallback + 46
11 CoreFoundation 0x01785ca5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
12 CoreFoundation 0x017859db __CFRunLoopDoSource1 + 523
13 CoreFoundation 0x017b068c __CFRunLoopRun + 2156
14 CoreFoundation 0x017af9d3 CFRunLoopRunSpecific + 467
15 CoreFoundation 0x017af7eb CFRunLoopRunInMode + 123
16 UIKit 0x00247d9c -[UIApplication _run] + 840
17 UIKit 0x00249f9b UIApplicationMain + 1225
18 SimpleLineChart 0x000115dd main + 141
19 libdyld.dylib 0x01e51701 start + 1
20 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I wanted to draw two graphs overlapping each other to show the relative statistics of two different variables. I created two different instances of the graph and overlapped them like in the figure. the problem is, the max value of y for green graph is 7000 and for purple its 8000 but they are at the same height. I understand that it is because the maxValue is considered to mark the highest point and the two graphs have their respective maxValue as the highest points. Is there any way to relate both the graphs and represent values accordingly?
First, a big thanks for this great lib... helps a lot!!
I would be nice to have the option to draw a "average" line (average value from all data values) in a different color.
Hi and thanks for this awesome tool.
When I wanna draw a chart with 6 numbers and all of them are 30.0 the app crashes and seems Line graph can not find the YAxis there. Would you mind please fix it ? Thanks
My graph is showing 100 at the bottom and then as numbers get lower, the line actually goes up. Here is the data and a screenshot:
The data in the array passed to the graph is actually drops during that period, not rises.
Here is my code:
#pragma mark GraphView
- (NSInteger)numberOfPointsInLineGraph:(BEMSimpleLineGraphView *)graph {
//ArrayOfValues = [NSMutableArray arrayWithObjects:@"44", @"42", @"30", @"100", @"0", nil];
return (int)[ArrayOfValues count]; // Number of points in the graph.
}
- (CGFloat)lineGraph:(BEMSimpleLineGraphView *)graph valueForPointAtIndex:(NSInteger)index {
//ArrayOfValues = [NSMutableArray arrayWithObjects:@"44", @"42", @"30", @"100", @"0", nil];
return [[ArrayOfValues objectAtIndex:index] floatValue]; // The value of the point on the Y-Axis for the index.
}
- (NSInteger)numberOfGapsBetweenLabelsOnLineGraph:(BEMSimpleLineGraphView *)graph {
return 9; // The number of hidden labels between each displayed label.
}
- (NSString *)lineGraph:(BEMSimpleLineGraphView *)graph labelOnXAxisForIndex:(NSInteger)index {
return [NSString stringWithFormat:@"%i", index];
}
- (void)lineGraph:(BEMSimpleLineGraphView *)graph didTouchGraphWithClosestIndex:(NSInteger)index {
self.graphTouch.text = [NSString stringWithFormat:@"%@%% Chance", [ArrayOfValues objectAtIndex:index]];
}
- (void)lineGraph:(BEMSimpleLineGraphView *)graph didReleaseTouchFromGraphWithClosestIndex:(CGFloat)index {
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.graphTouch.alpha = 0.0;
} completion:^(BOOL finished){
self.graphTouch.text = [NSString stringWithFormat:@" "];
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.graphTouch.alpha = 1.0;
} completion:nil];
}];
}
I really like this lib, it produces very lovely graphs with very little effort.
I'm trying to use it to create live graphs, which update in real-time (every second) and I'm seeing big spikes in memory and GPU usage. Could you give me any suggestions on how I could streamline the library to speed up this performance? I've dropped alpha to zero and turned off beziers - scratching the surface to be sure - are there any other low hanging fruit that I could tackle?
thanks again
Jason
self.myGraph = [[BEMSimpleLineGraphView alloc] initWithFrame:CGRectMake(10, 0, 300, 130)];
self.myGraph.backgroundColor = [UIColor clearColor];
self.myGraph.dataSource = self;
self.myGraph.delegate = self;
self.myGraph.enableTouchReport = YES;
self.myGraph.enablePopUpReport = YES;
self.myGraph.enableBezierCurve = YES;
self.myGraph.enableYAxisLabel = YES;
self.myGraph.alwaysDisplayDots = YES;
self.myGraph.colorYaxisLabel = [UIColor whiteColor];
self.myGraph.colorXaxisLabel = [UIColor whiteColor];
self.myGraph.colorTop = [UIColor clearColor];
self.myGraph.colorBottom = [UIColor clearColor];
I set enableBezierCurve = YES . Sometimes effective and sometimes ineffective
I would like to have linear gradient fill for chart, instead of just single color bottomColor.
Another good idea would be the ability to create a scatter chart.
I managed to fiddle with the code and get the scatter effect in place but the x labels are messed up. There is nothing wrong with the project, rather than my code.
The idea behind the scatter chart is that I hide the bezier curves and show only the dots without the x labels showing up. Since the scatter dots are way more than the x labels I must find a way to show predefined labels for the x-axis that should span across all the width of the chart.
Just wanted to say thanks again for the chart and if you have time we could discuss the possibility of a scatter plot if you are interested.
I'used BEMSimpleLineGraphView to draw my measurements that may have points with the same X-value (date).
The expected result should be draw the two values on a vertical line cause they have the same X value which is date, but they are drawn with a slope.
for example two points"
Point 1 : X -> 28-11-2013 , Y -> 50
Point 2 : X -> 28-11-2013 , Y -> 80
They should be drawn at the same vertical line, but they are drawn with slope.
Hola,
What do you think about an option to start registering user touch as soon as a touch event occurs, like a user touching the screen, versus the way it is now where a user has to begin panning on the graph before touch events are registered? I could see this improving discoverability a bit by any touch resulting in some action. Clearly this would need to be an option though, because that amount of responsiveness might be too heavy for some applications.
Just a thought. Curious what you think.
Thanks,
How do you use the lower graph property in the feature branch?
I've tried declaring firstGraph and secondGraph as a property and doing the following:
self.firstGraph.lowerGraph = self.secondGraph;
but to no avail. Can someone give me an example of how to use lowerGraph?
Thanks
When animationGraphEntranceTime=0.0
, alwaysDisplayDots=YES
is not showing dots. However the dots will appear ( and stays) once i pan through the graph.
The background reference line thickness is varying when animationGraphEntranceTime=0.0
and when it is having some value greater than 0.
animationGraphEntranceTime=0.5
animationGraphEntranceTime=0.0
Reference line is taking colorLine
of graph but usually not the case. Can we set it explicitly?
When run into device show error on -[BEMSimpleLineGraphView drawLines] at BEMSimpleLineGraphView.m:318:
Im replace my last version for the new one, in the simulator run perfect. BTW: its fabulous your charts great job, THANKS A LOT.
(void)drawLines {
for (UIView subview in [self subviews]) {
if ([subview isKindOfClass:[BEMLine class]])
[subview removeFromSuperview];
}
BEMLine *line = [[BEMLine alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
line.opaque = NO;
line.alpha = 1;
line.backgroundColor = [UIColor clearColor];
line.topColor = self.colorTop;
line.bottomColor = self.colorBottom;
line.topAlpha = self.alphaTop;
line.bottomAlpha = self.alphaBottom;
line.lineWidth = self.widthLine;
line.lineAlpha = self.alphaLine;
line.bezierCurveIsEnabled = self.enableBezierCurve;
line.arrayOfPoints = yAxisValues; // <-- this line
/ Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BEMLine setArrayOfPoints:]: unrecognized selector sent to instance 0x135528cc0' */
line.color = self.colorLine;
line.animationTime = self.animationGraphEntranceTime;
[self addSubview:line];
[self sendSubviewToBack:line];
}
I like having the option to auto-scale the Y axis for the graph, but I'd also like to be able to simply show absolute values. I'm currently hacking around this by auto-appending a value at the upper & lower range of my scale (40 & 180), so the graph auto scales between these values.
It would be great to have an option to set the scale to a range of values, on init (perhaps allowing for this to be set again later), rather than constantly autoscaling the graph.
Ever think of adding Y-Axis label?
280MB memory consumption with nearly 100 data input, a bit more data will cause application terminated for memory pressure.
For example value of 1 on day 1 is entered and value of 1 on day 2 is entered will cause the code to crash.
The x-axis labels currently show up below the frame and the background is the color/alphaBottom
. This is not the same for the y-axis. The background is the backgroundColor
. This can be avoided by making the background a solid color, but any other styling will get you in trouble. The example looks fine, but a white backgroundColor with different alpha top/bottom has issues (that i'm currently experiencing).
Additionally, some y-axis labels are cutoff and only display "...". Personally, I would like to see this as just a smaller font if it cannot fit.
A way to avoid the above issues all together would to have the y-axis labels appear inside the graph's frame (with the y-axis). This would be the best solution to me.
If you are looking for new features to implement, a feature I would like is the ability to set a static value for the x-axis maximum and x-axis label, so if there is not enough entries to fill the graph, you will see a partially filled graph.
Follow-up of the conversation on issue #30. See specifically point2.
The feature branch now supports Y-axis labels thanks to @japanconman (see commit b5f21a2 & PR #32).
This feature is still being tested but so far seems to be working pretty well.
@Diaonic pointed out on a conversation on Gitter that the labels show too many numbers after the decimals point.
I'm using this lib to graph data in realtime, appending new data as it arrives (Right To Left).
After a while, all the data gets bunched up and hard to read. Currently I'm trimming the earlier data, so the graph only shows the last 30 seconds or so.
It'd be nice if the user could 'scroll' left-right to see their graph history.
Currently seems like you can only show one line at a time. Any plans for adding 2 or more lines on the same graph?
Thanks
I am getting below error when touch graph, both numberOfPointsInLineGraph and valueForPointAtIndex return exactly two objects. So, I am wondering where 4294967196 comes from?
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 4294967196 beyond bounds [0 .. 1]'
Thanks for this awesome tool. I'm trying to use it, but when I have only one dot it cannot draw the chart and crashes.
Has this functionality been replaced by something else? Thanks for the great component, by the way.
Follow-up of the conversation on issue #30. See specifically point4.
This feature would allow the user to draw reference lines according to the axis labels. See the red arrows on the picture above.
The work has been started by @Sam-Spencer (see commit 2b16d64). Only vertical reference lines (X-axis) and an X-axis frame are supported for now.
Hello @Boris-Em, Thanks for sharing this excellent control.
Another great feature for this which would be easy to implement, is to allow the user to show/hide the bezier completely and just show the dots. What do you think?
I want to show two lines in my graph, so I'm using a work-around where I add two graphs to my view, and make the top graph's background color clear. It works great.
My only problem is only the top graph will recognize the pan gesture that displays the values. Is there any way to pass the pan gesture along to bottom graph, so I can have both values displayed on the pan gesture?
Or maybe just add a feature for showing two lines in the same graph object?
Thanks!
Are multiple lines (aka series) currently supported? Thanks!
When labelOnXAxisForIndex
returns a different amount of strings than numberOfPointsInLineGraph
, the app crashes.
In this scenario, the labels shouldn't be displayed on the X-axis, but the app shouldn't return an exception.
I'm trying to implement BEMSimpleLineGraph
in my Project and so far everything is good, but there doesn't seem to be a method to set a Maximum Point for Y-Axis. The valueForPointAtIndex
for my Graph would usually be between 3-7 but I'd like the graph's Y-Axis to be up to 10.
How would I make this happen?
I'm wondering if it's possible to use NSDate objects for the X-axis labels, rather than text? This could be quite a large feature to implement, but I'm curious - have you considered adding it? Why would I want to do this?
What do you think?
Perhaps I'm wrong (as I've only just started implementing this control in an app) but it seems at first glance (without running the code) that the delegate receiver is also used as a datasource?
I cannot find a dataSource
property to set on the line graph itself either? If I am incorrect, ignore this; if I am correct, I will submit a PR so that the datasource and delegate can have different receivers (more flexible design).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.