bar chart - iPad: How can I create a dynamic barchart using CGAffineTransformScale? -
i trying create animated barchart scaling bar (slider) , translating endcap. endcap works expected, however, "slider" translates when try scale horizontally.
-(void) animatebaropen: (nsinteger) rowindex { nslog(@"%s: row=%d %@", __function__, rowindex, [self.values objectatindex:rowindex]); nsmutabledictionary *row = [self.values objectatindex:rowindex]; uiimageview *slider = [row objectforkey:@"slider"]; uiimageview *endcap = [row objectforkey:@"image"]; uilabel *labelinfo = [row objectforkey:@"label"]; [labelinfo settext: [nsstring stringwithformat: @"%@ %@", [row objectforkey:@"quantity"], [row objectforkey:@"color"]]]; [labelinfo settextcolor: productcolor]; float quantity = [(nsnumber*) [row objectforkey:@"quantity"] floatvalue]; float tx = 10.0f * quantity; float sx = -40.0f * quantity; [uiview beginanimations:@"open" context:nil]; [uiview setanimationduration:0.25]; [uiview setanimationdelay:0.0]; [uiview setanimationcurve:uiviewanimationcurveeaseinout]; slider.transform = cgaffinetransformscale(cgaffinetransformidentity, sx, 1.0f); endcap.transform = cgaffinetransformtranslate(cgaffinetransformidentity, tx, 0.0f); labelinfo.transform = cgaffinetransformtranslate(cgaffinetransformidentity, tx, 0.0f); [uiview commitanimations]; }
ok - found ref explaining issue allowed me fix code. basically, since scaling based upon view's center property, therefore translates origin. result, have (re-)translate view location expected translate ratio of translation distance of location scaling moved.
demystifying cgaffinetransform
below code (that works) , notice computation of ratio of width before-to-after , translating amount. @ computation sx
, second computation of tx
(after animation). thought both should go in animation, not work might expect if second translation inside begin/commit.
also note: left of cosmetic code displaying colorful caption @ tip of bar.
-
(void) animatebaropen: (nsinteger) rowindex withduration: (nstimeinterval) duration { if (verbose_log) { nslog(@"%s: row=%d %@", __function__, rowindex, [self.values objectatindex:rowindex]); } nsmutabledictionary *rowvalues = [self.values objectatindex:rowindex]; nsmutabledictionary *rowoutlets = [self.iboutlets objectatindex:rowindex]; uicolor *productcolor = [infographview colorbyname: [rowvalues objectforkey: @"color"]]; uiimageview *slider = [rowoutlets objectforkey:@"slider"]; uiimageview *endcap = [rowoutlets objectforkey:@"image"]; uilabel *labelinfo = [rowoutlets objectforkey:@"label"]; nsassert1(labelinfo != nil, @"labelinfo null??", nil); [labelinfo setbackgroundcolor: productcolor]; // (255, 253, 208) uicolor *creamcolor = [uicolor colorwithred:255.0/255.0f green:253.0/255.0f blue:208.0/255.0f alpha:0.9]; [labelinfo settextcolor: creamcolor]; if ([(nsstring*)[rowvalues objectforkey:@"color"] isequaltostring:@"black"]) { [labelinfo setshadowcolor: [uicolor graycolor]]; } else { [labelinfo setshadowcolor: [uicolor blackcolor]]; } [labelinfo settext: [nsstring stringwithformat: @"%@ %@", [rowvalues objectforkey:@"quantity"], [rowvalues objectforkey:@"color"]]]; [slider sethidden:yes]; [slider setalpha: 0.7f]; float rangescale = [self computerangescale: self.values forwidth: cgrectgetwidth(self.frame) - margins]; slider.transform = cgaffinetransformidentity; float quantity = [(nsnumber*) [rowvalues objectforkey:@"quantity"] floatvalue]; float tx = rangescale * quantity; float sx = tx / cgrectgetwidth(slider.frame); // (cgrectgetwidth(endcap.frame) - cgrectgetwidth(slider.frame)); float sliderwidth = cgrectgetwidth(slider.frame); [slider sethidden:(rowindex == -1)]; [uiview beginanimations:@"open" context:nil]; [uiview setanimationduration:duration]; [uiview setanimationcurve:uiviewanimationcurveeaseinout]; slider.transform = cgaffinetransformscale(cgaffinetransformidentity, sx, 1.0f); endcap.transform = cgaffinetransformtranslate(cgaffinetransformidentity, tx, 0.0f); labelinfo.transform = cgaffinetransformtranslate(cgaffinetransformidentity, tx, (-rowindex*1.0f)); [labelinfo setalpha:1.0]; [uiview commitanimations]; tx = 1.0f * (cgrectgetwidth(slider.frame) - sliderwidth) / (sx*2.0f); slider.transform = cgaffinetransformtranslate(slider.transform, tx, 0.0f); [slider sethidden:no]; }
Comments
Post a Comment