i'm working core plot on xcode , want plot real-time incoming data via bluetooth. used cpttestapp mac os x example , tried adapt specific case. first 60 points added it's supposed , due following unaltered code:
-(void)setupscatterplots { static bool hasdata = no; // create 1 plot uses bindings cptscatterplot *boundlineplot = [[cptscatterplot alloc] init]; boundlineplot.identifier = bindingsplot; cptmutablelinestyle *linestyle = [boundlineplot.datalinestyle mutablecopy]; linestyle.miterlimit = 1.0; linestyle.linewidth = 2.0; linestyle.linecolor = [cptcolor redcolor]; boundlineplot.datalinestyle = linestyle; [self.graph addplot:boundlineplot]; [boundlineplot bind:cptscatterplotbindingxvalues toobject:self withkeypath:@"arrangedobjects.x" options:nil]; [boundlineplot bind:cptscatterplotbindingyvalues toobject:self withkeypath:@"arrangedobjects.y" options:nil]; // set plot delegate, know when symbols have been touched // display annotation when symbol touched boundlineplot.delegate = self; boundlineplot.plotsymbolmarginforhitdetection = 5.0; if ( !hasdata ) { // add initial data contentarray = [nsmutablearray arraywithcapacity:100]; ( nsuinteger = 0; < 60; i++ ) { nsnumber *x = @(1.0 + * 0.05); nsnumber *y = @(1.2 * arc4random() / (double)uint32_max + 1.2); [contentarray addobject:@{ @"x": x, @"y": y } ]; } self.content = contentarray; hasdata = yes; } // auto scale plot space fit plot data // extend y range 10% neatness cptxyplotspace *plotspace = (cptxyplotspace *)self.graph.defaultplotspace; plotspace.allowsmomentum = yes; [plotspace scaletofitplots:@[boundlineplot]]; cptplotrange *xrange = plotspace.xrange; cptmutableplotrange *yrange = [plotspace.yrange mutablecopy]; [yrange expandrangebyfactor:cptdecimalfromdouble(1.1)]; plotspace.yrange = yrange; // restrict y range global range plotspace.globalxrange = [cptplotrange plotrangewithlocation:cptdecimalfromdouble(-1.0) length:cptdecimalfromdouble(10.0)]; plotspace.globalyrange = [cptplotrange plotrangewithlocation:cptdecimalfromdouble(-1.0) length:cptdecimalfromdouble(5.0)]; // set x , y shift match new ranges cgfloat length = xrange.lengthdouble; self.xshift = length - 3.0; length = yrange.lengthdouble; self.yshift = length - 2.0; } i'm using method called insertdata looks this:
-(void)insertdata:(uint32 *) buf :(uint32 *) { [contentarray addobject:@{ @"x": i, @"y": buf } ]; nslog(@"%@",contentarray); self.content = contentarray; } where buf incoming data. when call insertdata method, data appended array tab on interface doesn't change, neither plot.
can me please? !
i tried convert int nsnumber using following :
nsnumber *ni = @(*i); nsnumber *nbuf = @(*buf); and:
nsnumber *ni = [nsnumber numberwithunsignedint:(*i); nsnumber *nbuf = [nsnumber numberwithunsignedint:(*buf); i tried reload stuff found on internet
but none of worked either.
#import "controller.h" #import "heartratemonitorappdelegate.h" static const cgfloat kzdistancebetweenlayers = 20.0; static nsstring *const bindingsplot = @"bindings plot"; static nsmutablearray *contentarray; @interface controller() @property (nonatomic, readwrite, strong) iboutlet cptgraphhostingview *hostview; @property (nonatomic, readwrite, strong) cptxygraph *graph; @property (nonatomic, readwrite, strong) cptplotspaceannotation *symboltextannotation; -(void)setupgraph; -(void)setupaxes; -(void)setupscatterplots; @end #pragma mark - @implementation controller @synthesize hostview; @synthesize graph; @synthesize symboltextannotation; +(void)initialize { [nsvaluetransformer setvaluetransformer:[cptdecimalnumbervaluetransformer new] forname:@"cptdecimalnumbervaluetransformer"]; } -(void)awakefromnib { [super awakefromnib]; self.xshift = 0.0; self.yshift = 0.0; [self setupgraph]; [self setupaxes]; [self setupscatterplots]; } -(id)newobject:(uint32 *) buf :(uint32 *) { nslog(@"buf = %d", *buf); nsnumber *x1 = @(*i); nsnumber *y1 = @(*i); return @{ @"x": x1, @"y": y1 }; } #pragma mark - #pragma mark graph setup methods -(void)setupgraph { // create graph , apply dark theme cptxygraph *newgraph = [[cptxygraph alloc] initwithframe:nsrecttocgrect(self.hostview.bounds)]; cpttheme *theme = [cpttheme themenamed:kcptdarkgradienttheme]; [newgraph applytheme:theme]; self.hostview.hostedgraph = newgraph; self.graph = newgraph; // graph padding newgraph.paddingleft = 0.0; newgraph.paddingtop = 0.0; newgraph.paddingright = 0.0; newgraph.paddingbottom = 0.0; // plot area delegate newgraph.plotareaframe.plotarea.delegate = self; } -(void)setupaxes { // setup scatter plot space cptxyplotspace *plotspace = (cptxyplotspace *)self.graph.defaultplotspace; plotspace.allowsuserinteraction = yes; plotspace.delegate = self; // grid line styles cptmutablelinestyle *majorgridlinestyle = [cptmutablelinestyle linestyle]; majorgridlinestyle.linewidth = 0.75; majorgridlinestyle.linecolor = [[cptcolor colorwithgenericgray:0.2] colorwithalphacomponent:0.75]; cptmutablelinestyle *minorgridlinestyle = [cptmutablelinestyle linestyle]; minorgridlinestyle.linewidth = 0.25; minorgridlinestyle.linecolor = [[cptcolor whitecolor] colorwithalphacomponent:0.1]; cptmutablelinestyle *redlinestyle = [cptmutablelinestyle linestyle]; redlinestyle.linewidth = 10.0; redlinestyle.linecolor = [[cptcolor redcolor] colorwithalphacomponent:0.5]; // axes // label x axis fixed interval policy cptxyaxisset *axisset = (cptxyaxisset *)self.graph.axisset; cptxyaxis *x = axisset.xaxis; x.majorintervallength = cptdecimalfromdouble(0.5); x.orthogonalcoordinatedecimal = cptdecimalfromdouble(0.0); x.minorticksperinterval = 2; x.majorgridlinestyle = majorgridlinestyle; x.minorgridlinestyle = minorgridlinestyle; nsarray *exclusionranges = @[[cptplotrange plotrangewithlocation:cptdecimalfromdouble(1.99) length:cptdecimalfromdouble(0.02)], [cptplotrange plotrangewithlocation:cptdecimalfromdouble(0.99) length:cptdecimalfromdouble(0.02)], [cptplotrange plotrangewithlocation:cptdecimalfromdouble(2.99) length:cptdecimalfromdouble(0.02)]]; x.labelexclusionranges = exclusionranges; // label y automatic label policy. cptxyaxis *y = axisset.yaxis; y.labelingpolicy = cptaxislabelingpolicyautomatic; y.orthogonalcoordinatedecimal = cptdecimalfromdouble(0.0); y.minorticksperinterval = 2; y.preferrednumberofmajorticks = 8; y.majorgridlinestyle = majorgridlinestyle; y.minorgridlinestyle = minorgridlinestyle; y.labeloffset = 10.0; exclusionranges = @[[cptplotrange plotrangewithlocation:cptdecimalfromdouble(1.99) length:cptdecimalfromdouble(0.02)], [cptplotrange plotrangewithlocation:cptdecimalfromdouble(0.99) length:cptdecimalfromdouble(0.02)], [cptplotrange plotrangewithlocation:cptdecimalfromdouble(3.99) length:cptdecimalfromdouble(0.02)]]; y.labelexclusionranges = exclusionranges; } -(void)setupscatterplots { static bool hasdata = no; // create 1 plot uses bindings cptscatterplot *boundlineplot = [[cptscatterplot alloc] init]; boundlineplot.identifier = bindingsplot; cptmutablelinestyle *linestyle = [boundlineplot.datalinestyle mutablecopy]; linestyle.miterlimit = 1.0; linestyle.linewidth = 2.0; linestyle.linecolor = [cptcolor redcolor]; boundlineplot.datalinestyle = linestyle; [self.graph addplot:boundlineplot]; [boundlineplot bind:cptscatterplotbindingxvalues toobject:self withkeypath:@"arrangedobjects.x" options:nil]; [boundlineplot bind:cptscatterplotbindingyvalues toobject:self withkeypath:@"arrangedobjects.y" options:nil]; // set plot delegate, know when symbols have been touched // display annotation when symbol touched boundlineplot.delegate = self; boundlineplot.plotsymbolmarginforhitdetection = 5.0; if ( !hasdata ) { // add initial data contentarray = [nsmutablearray arraywithcapacity:100]; ( nsuinteger = 0; < 5; i++ ) { nsnumber *x = @(1.0 + * 0.05); nsnumber *y = @(1.2 * arc4random() / (double)uint32_max + 1.2); [contentarray addobject:@{ @"x": x, @"y": y } ]; } self.content = contentarray; hasdata = yes; } // auto scale plot space fit plot data // extend y range 10% neatness cptxyplotspace *plotspace = (cptxyplotspace *)self.graph.defaultplotspace; plotspace.allowsmomentum = yes; [plotspace scaletofitplots:@[boundlineplot]]; cptplotrange *xrange = plotspace.xrange; cptmutableplotrange *yrange = [plotspace.yrange mutablecopy]; [yrange expandrangebyfactor:cptdecimalfromdouble(1.1)]; plotspace.yrange = yrange; // restrict y range global range plotspace.globalxrange = [cptplotrange plotrangewithlocation:cptdecimalfromdouble(-1.0) length:cptdecimalfromdouble(10.0)]; plotspace.globalyrange = [cptplotrange plotrangewithlocation:cptdecimalfromdouble(-1.0) length:cptdecimalfromdouble(5.0)]; // set x , y shift match new ranges cgfloat length = xrange.lengthdouble; self.xshift = length - 3.0; length = yrange.lengthdouble; self.yshift = length - 2.0; } -(void)insertdata:(uint32 *) buf :(uint32 *) { nsnumber *ni = @(*i); //nsnumber *nbuf = @(*buf); [contentarray addobject:@{ @"x": ni, @"y": ni } ]; self.content = contentarray; [graph reloaddata]; } #pragma mark - #pragma mark plot data source methods -(nsuinteger)numberofrecordsforplot:(cptplot *)plot { if ( [plot iskindofclass:[cptbarplot class]] ) { return 8; } else { return [self.arrangedobjects count]; } } -(id)numberforplot:(cptplot *)plot field:(nsuinteger)fieldenum recordindex:(nsuinteger)index { nsnumber *num; if ( [plot iskindofclass:[cptbarplot class]] ) { num = @( (index + 1) * (index + 1) ); if ( [plot.identifier isequal:bindingsplot] ) { num = @(num.integervalue - 10); } } else { nsstring *key = (fieldenum == cptscatterplotfieldx ? @"x" : @"y"); num = (self.arrangedobjects)[index][key]; if ( fieldenum == cptscatterplotfieldy ) { num = @([num doublevalue] + 1.0); } } return num; } -(cptlayer *)datalabelforplot:(cptplot *)plot recordindex:(nsuinteger)index { if ( [(nsstring *)plot.identifier isequaltostring : bindingsplot] ) { return (id)[nsnull null]; // don't show label } else if ( [(nsstring *)plot.identifier isequaltostring : bindingsplot] && (index < 4) ) { return (id)[nsnull null]; } else if ( index % 4 ) { return (id)[nsnull null]; } else { return nil; // use default label style } } #pragma mark - #pragma mark cptscatterplot delegate method -(void)scatterplot:(cptscatterplot *)plot plotsymbolwasselectedatrecordindex:(nsuinteger)index { cptplotspaceannotation *annotation = self.symboltextannotation; if ( annotation ) { [self.graph.plotareaframe.plotarea removeannotation:annotation]; self.symboltextannotation = nil; } // setup style annotation cptmutabletextstyle *hitannotationtextstyle = [cptmutabletextstyle textstyle]; hitannotationtextstyle.color = [cptcolor whitecolor]; hitannotationtextstyle.fontsize = 16.0f; hitannotationtextstyle.fontname = @"helvetica-bold"; // determine point of symbol in plot coordinates nsdictionary *datapoint = (self.arrangedobjects)[index]; nsnumber *x = datapoint[@"x"]; nsnumber *y = datapoint[@"y"]; nsarray *anchorpoint = @[x, y]; // add annotation // first make string y value nsnumberformatter *formatter = [[nsnumberformatter alloc] init]; [formatter setmaximumfractiondigits:2]; nsstring *ystring = [formatter stringfromnumber:y]; // add annotation plot area cpttextlayer *textlayer = [[cpttextlayer alloc] initwithtext:ystring style:hitannotationtextstyle]; annotation = [[cptplotspaceannotation alloc] initwithplotspace:self.graph.defaultplotspace anchorplotpoint:anchorpoint]; annotation.contentlayer = textlayer; annotation.displacement = cgpointmake(0.0, 20.0); [self.graph.plotareaframe.plotarea addannotation:annotation]; self.symboltextannotation = annotation; } #pragma mark - #pragma mark plot area delegate method -(void)plotareawasselected:(cptplotarea *)plotarea { // remove annotation cptplotspaceannotation *annotation = self.symboltextannotation; if ( annotation ) { [self.graph.plotareaframe.plotarea removeannotation:annotation]; self.symboltextannotation = nil; } } #pragma mark - #pragma mark pdf / image export -(ibaction)exporttopdf:(id)sender { nssavepanel *pdfsavingdialog = [nssavepanel savepanel]; [pdfsavingdialog setallowedfiletypes:@[@"pdf"]]; if ( [pdfsavingdialog runmodal] == nsokbutton ) { nsdata *dataforpdf = [self.graph dataforpdfrepresentationoflayer]; [dataforpdf writetourl:[pdfsavingdialog url] atomically:no]; } } -(ibaction)exporttopng:(id)sender { nssavepanel *pngsavingdialog = [nssavepanel savepanel]; [pngsavingdialog setallowedfiletypes:@[@"png"]]; if ( [pngsavingdialog runmodal] == nsokbutton ) { nsimage *image = [self.graph imageoflayer]; nsdata *tiffdata = [image tiffrepresentation]; nsbitmapimagerep *tiffrep = [nsbitmapimagerep imagerepwithdata:tiffdata]; nsdata *pngdata = [tiffrep representationusingtype:nspngfiletype properties:nil]; [pngdata writetourl:[pngsavingdialog url] atomically:no]; } } #pragma mark - #pragma mark printing -(ibaction)printdocument:(id)sender { nsprintinfo *printinfo = [nsprintinfo sharedprintinfo]; nsrect printrect = nszerorect; printrect.size.width = (printinfo.papersize.width - printinfo.leftmargin - printinfo.rightmargin) * printinfo.scalingfactor; printrect.size.height = (printinfo.papersize.height - printinfo.topmargin - printinfo.bottommargin) * printinfo.scalingfactor; self.hostview.printrect = printrect; nsprintoperation *printoperation = [nsprintoperation printoperationwithview:self.hostview printinfo:printinfo]; [printoperation runoperationmodalforwindow:self.hostview.window delegate:self didrunselector:@selector(printoperationdidrun:success:contextinfo:) contextinfo:null]; } -(void)printoperationdidrun:(nsprintoperation *)printoperation success:(bool)success contextinfo:(void *)contextinfo { // print delegate }
core plot expects data values nsnumber instances, not plain integers. can use nsdecimalnumber (a subclass of nsnumber) if need preserve full decimal precision.
since you're using data bound nsarraycontroller, -reloaddata , related methods have no effect. used when providing data through datasource. that's method available on ios why of sample code , demos on web use it.
once nsarraycontroller initialized, should use methods add or remove data rather updating content array directly. cpttestapp demo uses -insertobject:atarrangedobjectindex: , -removeobjectatarrangedobjectindex: this.
Comments
Post a Comment