4

I am trying to create an animated radial chart that looks like the activity app created by Apple. I provide an image to show what I would like as result:

Example

Do you know how to obtain this result? If you have any idea could you please focus on the following points?

  1. Create the gradient inside each circle
  2. Create the shadow on the head of the circle

Thank you very much in advance.

GrizzlyBear
  • 1,098
  • 1
  • 13
  • 27

2 Answers2

9

Check out my custom control, I tried to make it as close as possible to the Activity app design, and everything is customizable.

https://github.com/maxkonovalov/MKRingProgressView


The basic idea behind the algorithm is quite simple.

To draw arc line with changing color:

  1. Generate a conical gradient image

Conical gradient

You can use a prerendered image from Photoshop or generate your own dynamically. I use a gradient image generator from here: https://github.com/maxkonovalov/MKGradientView.

  1. Clip gradient image to show only the arc

Clipped gradient

CGContextSaveGState(ctx)
CGContextAddPath(ctx, arcPath)
CGContextClip(ctx)
CGContextDrawImage(ctx, gradientRect, gradientImage)
CGContextRestoreGState(ctx)

Drawing the shadow is even simpler:

  1. Draw shadow behind your progress arc (shown with 50% opacity here)

Shadow

I draw a circle shape matching arc's end for the shadow.

CGContextSetShadow(ctx, offset, shadowRadius)
CGContextAddPath(ctx, shadowPath)
CGContextSetFillColorWithColor(ctx, shadowColor)
CGContextFillPath(ctx)
  1. Clip the shadow to fit into the progress circle

Shadow clipped

CGContextSaveGState(ctx)
CGContextAddPath(ctx, circlePath)
CGContextClip(ctx)
// Draw shadow...
CGContextRestoreGState(ctx)

And the final result looks like this:

Circle progress view

maxkonovalov
  • 3,651
  • 34
  • 36
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Luke Oct 22 '15 at 22:55
  • @Luke: Updated my answer with more details on the algorithm – maxkonovalov Oct 23 '15 at 13:40
  • I don't think the shadow will show once it reaches 100% or more. The shadow won't cover the red area once the blue area reaches say 130%, which it does in the Apple Watch screenshot in the question. – Graham Perks Apr 16 '18 at 16:40
  • @GrahamPerks that's true, to make it work the same way as Apple Watch app requires a few hacks not covered here for simplicity. It all works as expected though in the lib I linked at the top of my answer, you can check the source for more details on the implementation. – maxkonovalov Apr 17 '18 at 08:09
  • @maxkonovalov Thank you for the great answer. Can you elaborate on how to deal with the progress being over 100%? – wcandillon Jan 03 '20 at 07:03
  • @wcandillon The algorithm is as follows: the gradient arc is always drawn up to a certain angle, until the shadow intersects with the arc's start (about 90% progress). After that (90-100% progress), the whole gradient arc is rotated, and another arc filled with start color is drawn below, which allows to make the ring feel wrapped over itself. For progress values greater than 100% the whole ring is just rotated. For more details take a look at MKRingProgressView's implementation. – maxkonovalov Jan 14 '20 at 14:26
  • Yes, I managed to crack it thank you! It was hard to see "this trick". The code is available at https://github.com/wcandillon/can-it-be-done-in-react-native/tree/master/season3/src/AppleActivity, I've done a video about it that is scheduled to be released tomorrow at https://www.youtube.com/user/wcandill – wcandillon Jan 15 '20 at 15:21
  • @maxkonovalov thank you for paving the way with that animation. – wcandillon Jan 15 '20 at 15:21
0

This isn't quite what you need as it appears to generate the image for you, but you could get some good info from the source.

https://github.com/hmaidasani/RadialChartImageGenerator

Dan Loughney
  • 4,647
  • 3
  • 25
  • 40
  • I already found that but it's just a tool to generate a set of images to be used for the AppleWatch. I need to create the progress for an iOS application (iPhone). – GrizzlyBear Jul 17 '15 at 18:22