core plot datasource - issue - datasource

I have a question for optimize a core plot graph, if I want to plot the function y=8*sin(x) I use a parse and I get the value of a range (for example -5,+5), after calculate it I plot the graph.
If I drag up or down the plot some value are covered, so they are unnecessary and I can remove it, after this add some point on visible range for have a better line.
Now I have a datasource of more interval, 3 array with the y value of this interval: -5,-2 one of 0,3 and one 4,5 (this number are for example). How can I plot this line on my plot View, I need to add some code like this:
CPTScatterPlot *xSquaredPlot = [[CPTScatterPlot alloc] initWithFrame:graph.defaultPlotSpace.accessibilityFrame];
xSquaredPlot.identifier = #"Grafico";
xSquaredPlot.interpolation = CPTScatterPlotInterpolationLinear;
xSquaredPlot.delegate = self;
CPTMutableLineStyle *lineStyleFunc = [CPTMutableLineStyle lineStyle];
lineStyleFunc.lineWidth = 1.0f;
lineStyleFunc.lineColor = [CPTColor redColor];
xSquaredPlot.dataLineStyle = lineStyleFunc;
xSquaredPlot.dataSource = self;
[graph addPlot:xSquaredPlot];
but the problem i that I don't know how line I have, I need to create it dynamically, how can I do it? adding this code when I create the arrays of new interval? but when I need to update datasource?

Core Plot will skip drawing points that fall outside the visible plot area when it can, so you don't have to worry too much about doing that in your datasource. You don't want to be adding and removing a lot of data points as the user scrolls around—that will just cause more work for the plotting code and slow it down.
Since you are plotting a function, one thing you can do is only generate data points in a fairly small range, say just slightly outside the visible x-range. Use a plot space delegate to monitor changes and add points as needed when the user scrolls or zooms the graph.
Use the -insertDataAtIndex:numberOfRecords: method to add data points to the plot. This will have better performance than -reloadData which forces the plot to load all of its data, not just the new values.

Related

How would one draw an arbitrary curve in createJS

I am attempting to write a function using createJS to draw an arbitrary function and I'm having some trouble. I come from a d3 background so I'm having trouble breaking out of the data-binding mentality.
Suppose I have 2 arrays xData = [-10, -9, ... 10] and yData = Gaussian(xData) which is psuedocode for mapping each element of xData to its value on the bell curve. How can I now draw yData as a function of xData?
Thanks
To graph an arbitrary function in CreateJS, you draw lines connecting all the data points you have. Because, well, that's what graphing is!
The easiest way to do this is a for loop going through each of your data points, and calling a lineTo() for each. Because the canvas drawing API starts a line where you last 'left off', you actually don't even need to specify the line start for each line, but you DO have to move the canvas 'pen' to the first point before you start drawing. Something like:
// first make our shape to draw into.
let graph = new createjs.Shape();
let g = graph.graphics
g.beginStroke("#000");
xStart = xData[0];
yStart = yourFunction(xData[0]);
g.moveTo(xStart, yStart);
for( let i = 1; i < xData.length; i++){
nextX = xData[i], but normalized to fit on your graph area;
nextY = yourFunction(xData[i]), but similarly normalized;
g.lineTo(nextX, nextY);
}
This should get a basic version of the function drawing! Note that the line will be pretty jagged if you don't have a lot of data points, and you'll have to treat (normalize) your data to make it fit onto your screen. For instance, if you start at -10 for X, that's off the screen to the left by 10 pixels - and if it only runs from -10 to +10, your entire graph will be squashed into only 20 pixels of width.
I have a codepen showing this approach to graphing here. It's mapped to hit every pixel on the viewport and calculate a Y value for it, though, rather than your case where you have input X values. And FYI, the code for graphing is all inside the 'run' function at the top - everything in the PerlinNoiseMachine class is all about data generation, so you can ignore it for the purposes of this question.
Hope that helps! If you have any specific follow-up questions or code samples, please amend your question.

Core Plot Gallery real time plot design criteria

I few curiosities from the RealTimePlot.m of the CorePlotGallery sample real time plot setup:
// Plot space
CPTXYPlotSpace * plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:#0.0 length:#(kMaxDataPoints - 2)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:#0.0 length:#1.0];
plotSpace.allowsUserInteraction = YES;
It notes a range of points - kMaxDataPoints, initially 52, which appears to be the visible range of plot points from the initial window/view size.
The delegate newData method trims the earliest point to be added, to maintain this queue but my question is how was this value (52) derived?
Is it possible to calc at run-time this visible range even when the user pinches / zooms?
Wouldn't it better to trim the point(s) afterwards - after adding, when the quantity is known of points added, from the range beginning?
It's a "magic number" derived by saying "that's looks good" rather than any empirical method. Of course you can calculate it based on the size of the plot area. Using a constant is just a shortcut. Because of the design of the app, we know that the graph won't change size on iOS, so it's a reasonable shortcut to make there.
I don't understand the last part of the question.

Core Plot bar Graph iPhone

I have followed this link http://www.gilthonwe.com/2012/06/09/stacked-bar-chart-coreplot-ios/ and have succeeded in making bar graph what i needed. but now i want something change in this graph i want 2 bar graph lines on single x axis date. i want bar graph like this one.
(source: tqn.com)
but i want 2 bars not 3.
What i have to change or how can i achieve to make this bar graph.
If it's just the bar graph I don't think you need the code provided in your link. The easiest way to achieve something like that would be to simple use CALayer to represent the bars in the graph. You just set their frames and backgroundcolors as needed, add them as sublayer to your view and your done (besides creating the axis and labels)
CALayer *layer = [[CALayer alloc] init];
layer.frame = /* ... */;
layer.backgroundColor = [[UIColor redColor] CGColor];
[someView.layer addSublayer:layer];
You should use two bar plots, one for each set of bars with the same fill. Use the barOffset on each plot to shift one a little bit to the left and the other a little to the right so they join above the bar location. See the Plot Gallery example app for sample code.

Coreplot editing plotspace

I came up with a small problem. Now, I've got a program which plots
graphs. For that I've set up few functions.
First when loaded the graph gets initialized with the plotspace
etc. Then when the user clicks a button, a new plot gets added to the
graph. But with that I have the necessity to change the
plotSpace.xRange and plotsPace.yRange. How can I do so after having
initialized the graph already?
Thanks for your thoughts!
You can change the plot space ranges at any point, not just on creation of the graph. Once you do so, the graph should adjust the displayed axis ranges onscreen. I don't believe you even need to reload the data for a given graph after this.
As an example, the following code should adjust the X range of a plot to be from 0 to 100:
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
[plotSpace setXRange:[CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(0) length:CPTDecimalFromInteger(100)]];
where graph is a CPTXYGraph instance, in this case.

Using CPTAnnotation in CorePlot DatePlot (iOS)

I am Using CorePlot in my app, and I want to display a annotation over the plotSymbol. I haven't found any code in the sample projects of the latest 0.9 version of CorePlot. After some research i have come to this point:
- (void)scatterPlot:(CPTScatterPlot *)plot plotSymbolWasSelectedAtRecordIndex:(NSUInteger)index
{
CPTLayerAnnotation *annot = [[CPTLayerAnnotation alloc]initWithAnchorLayer:graph];
CPTBorderedLayer * logoLayer = [[(CPTBorderedLayer *) [CPTBorderedLayer alloc] initWithFrame:CGRectMake(10,10,100,50)] autorelease];
CPTFill *fillImage = [CPTFill fillWithImage:[CPTImage imageForPNGFile:#"whatEver!"]];
logoLayer.fill = fillImage;
annot.contentLayer = logoLayer;
annot.rectAnchor=CPTRectAnchorTop;
[graph addAnnotation:annot];
}
But its obviously not working.... Can anybody help me?
My goal is to get an annotation over the selected plot symbol, similar to annotations in MKMapView.
Update
It is a DatePlot, just to clarify things and it is working with time intervals since 2001 on the x-axis.
There are several examples of this in the Core Plot example apps. The gradient scatter plot in the Plot Gallery app (and several other apps as well) use this method to attach a text label to the selected point. The point selection demo in the Mac version of CPTTestApp uses a second scatter plot to draw a crosshairs over the selected point.
Remember to set the plotSymbolMarginForHitDetection property on the scatter plot, too. The default is 0, which means you have to hit the center of the point exactly to register a touch.
There are two types of annotation in Core Plot. A CPTLayerAnnotation is anchored to a given Core Animation layer (the graph in your case). A CPTPlotSpaceAnnotation is anchored to a plot space coordinate (== data coordinate). Your comment below makes it sound like you want to use a plot space annotation instead of a layer annotation.