Set and update color of multiple graphical shapes by array?

Hello,

I have several graphical elements (50+) (rectangles) and I want to show and change color according to interaction (e.g. onTap) at different dates.

The status of the interaction is actually stored in an array.

How can I update / call all the graphical elements at once in an efficient way (without calling each graphical element)

How to call the onUpdate function out of Delegate.mc or do I have to update the view out of the onTap function?

How can I represent colors with numerical values (not hexadecimal or text)?

A small example and some general explanations would be great!

Thanks!

  • I have a post in this thread that does something similar to what you want, but I'm changing the size of a circle from the delegate and updating the screen,

    https://forums.garmin.com/developer/connect-iq/f/discussion/265858/access-variable-calculated-in-ontap-event-for-sizing-in-drawing-shapes

    Notice how I'm passing the view to the delegate, and then using WatchUi.requestUpdate() when I want the view to update.

    Not exactly what you want but the principals are the same.

  • Thanks, the update works.

    I need a bit more information about, how update a lot of graphical shapes in an efficient way (you had just 1 circle, so just 1 expression).  Is it possible to have an array e.g. with 50 elements and each can have a value and depending on theres values (change value e.g. by tap event) the color changes. But then I have to update all 50 elements at once. (for-loop with array?) How can I handle the different colortypes as numerical variables?

    Should I use drawables (the 50 elements have fixed positions)? how can I call all of them in a loop? is it possible to use numerical identifiers for the drawings? how is it possible the make the color variable (e.g. in combination with the status out of an array.e.g I call the first drawable and depending on the first cell of the array it can have 3 different colors....

    Are there any easer, better, faster alternatives?

  • If you want to use a layout/drawables then there will be overhead (your app will be bigger / use more memory), but it may be simpler to code.

    You can put the resource symbols in an array and loop through the array when you want to update the drawables.

    e.g.

    <drawables>
        <bitmap id="drawable_1" ... />
        <bitmap id="drawable_2" ... />
        ...
        
    <bitmap id="drawable_50" ... />
    </
    drawables>


    var drawables = [
        Rez.Drawables.drawable_1, // array index 0
        Rez.Drawables.drawable_2, // 1
        ...
        Rez.Drawables.drawable_50 // 49
    ];

    for
     (var i = 0; i < drawables.size(); i++) {
        var drawable = drawables[i];
        // draw drawable here
    }

    If you want "numerical IDs" for your colors, you do something similar to above and put your colors in an array. e.g. Say you have the following list of colors to rotate through:

    // say we have 10 colors to cycle through
    var colors = [
        Gfx.COLOR_BLACK, 
    // index 0
        Gfx.COLOR_WHITE, // 1
        ...
        Gfx.COLOR_DK_GREEN 
    // 9
    ];

    Then you would create another array which maps each drawable to a color:

    var drawable_colors = [
        
    9 // dark green; index 0 (drawable_1 is initially dark green)
        0// black; index 1
        1// white; index 2
        ...
        
    0 // black; index 49
    ];

    Any time you want to get the current color of a drawable, just access the array at the drawable index.

    Any time you want to "increment" the current color of a drawable, just increment the array item and wrap around to 0 if necessary:

    // increment drawable colors
    for (var i = 0; i < drawables.size(); i++) {
        drawable_colors[i] = (drawable_colors[i] + 
    1) % colors.size();
    }
  • Hi,

    Perfect! that's exactly what I was searching for! Thanks a lot also for the examples, these helped a lot!

    I would like to work with shapes (not bitmap graphics). The definition I use at the moment is:

    <drawable-list id="shape1" background="Graphics.COLOR_TRANSPARENT">
       <shape type="circle" x="78" y="160" radius="8" color="Graphics.COLOR_YELLOW" />
    </drawable-list>

    Here the color has to be predefined. How can I change it later shape by shape out of an array? Could you please detail your definition of drawables for this case and your last example where you change the colors.

  • You could just user dc.setColor() and dc.drawCircle() and not do it as a drawable list

    Have the array include x, y, foreground color, radius (etc)

  • ok, thank you.

    This works:

    var xkoord =[30,30];
    var ykoord =[50,50];
         
         dc.setColor(Graphics.COLOR_PINK, Graphics.COLOR_BLACK);  // creates circle

    I would like a filled circle
         
         dc.setFill(0xFF0000);
         dc.drawCircle(xkoord[0],ykoord[0],30);

    but I receive error message. What's wrong?

    Error: Symbol Not Found Error
    Details: Could not find symbol 'setFill'

    If I have 50+ graphical elements, which routine is faster yours or the example above?

  • Use dc.fillCircle() instead of dc.drawCircle() and skip the setFill()

    SetFill is only available on CIQ 4 devices like the venu2 and venu2s.

  • I works perfectly! Thank you! very elegant and minimalistic solution.

    Is there any performance restriction regarding array size, calls, loop size to be exected with 50-100 elements?

  • The more shapes you draw and how often you draw them impacts performance.  Remember each time onUpdate is called, you need to redraw everything.

    If your loops get to long, you'll trigger the watchdog timer.