DrawArcBatteryLife?

Could someone please make a drawArc example for battery life in segments where there will be a maximum of 5 segments (5segments 100% battery) and they will slowly decrease as the watch battery drains.?

I followed this thread: forums.garmin.com/.../drawarc-based-on-a-percentage

but that doesn't solve my request.

Thank you very much for the example.

  • I don't think the picture shown is what you want to do. Showing a continuous decrease using segments makes no sense. The image indicates that the respective segments are illuminated here:
    All 5 for state of charge > 80%
    4 segments for state of charge < 80% ...
    1 segment for state of charge < 20%

    For a continuous progression, an arc without interruptions would be selected.

  • The picture I attached is just my imagination. I want to create a total of 5 segments and when the battery is 100% charged, all segments will be green. if the battery goes down, the segments will slowly fade.

    There can be more of those segments, they just have to fit in the area at the bottom left of the watch display.

  • I doubt you'll notice any battery impact on a watch face.  Most of the time, the screen only gets updated every minute.

    As far as an example, I started with MonkeyC: New Project and created a very simple watch face, and added code to draw 5 arcs, each 8 degrees with a 2 degree gap, starting at 90 degrees, so upper right.

    Here's the code from the template, with comments for what I added.

    import Toybox.Graphics;
    import Toybox.Lang;
    import Toybox.System;
    import Toybox.WatchUi;

    class wfarcView extends WatchUi.WatchFace {
        //Add This
        var width,height,radius;
        var pen=5;
        //End Add

        function initialize() {
            WatchFace.initialize();
        }

        // Load your resources here
        function onLayout(dc as Dc) as Void {
            setLayout(Rez.Layouts.WatchFace(dc));
            //Add This
            width=dc.getWidth();
            height=dc.getHeight();
            radius=(width/2)-pen;
            //End Add
        }

        // Called when this View is brought to the foreground. Restore
        // the state of this View and prepare it to be shown. This includes
        // loading resources into memory.
        function onShow() as Void {
        }

        // Update the view
        function onUpdate(dc as Dc) as Void {
            // Get and show the current time
            var clockTime = System.getClockTime();
            var timeString = Lang.format("$1$:$2$", [clockTime.hour, clockTime.min.format("%02d")]);
            var view = View.findDrawableById("TimeLabel") as Text;
            view.setText(timeString);

            // Call the parent onUpdate function to redraw the layout
            View.onUpdate(dc);
            //Add This
            doArcs(dc);
            //End Add
        }

        //Add This
        function doArcs(dc) {
            var ang=90;
            dc.setColor(Graphics.COLOR_YELLOW, Graphics.COLOR_TRANSPARENT);
            dc.setPenWidth(pen);
            for(var i=0; i<5;i++) {
                dc.drawArc(width/2,height/2,radius, Graphics.ARC_CLOCKWISE,ang,ang-8);
                ang-=10;
            }
            dc.setPenWidth(1);      
        }
        //End Add

        // Called when this View is removed from the screen. Save the
        // state of this View here. This includes freeing resources from
        // memory.
        function onHide() as Void {
        }

        // The user has just looked at their watch. Timers and animations may be started here.
        function onExitSleep() as Void {
        }

        // Terminate any active timers and prepare for slow updates.
        function onEnterSleep() as Void {
        }

    }
    And here's the result in the sim:
    comment out the call to doArcs() in onUpdate to turn this off to compare on a real watch.
  • Here are 2 samples:

            var akku = System.getSystemStats().battery;    
            // for testing:
            //akku = computedValue;
            var scrWidth = System.getDeviceSettings().screenWidth;
            var scrHeight = System.getDeviceSettings().screenHeight;
            
            var penWidth = 15;
            var startAngle = 240;
            var endAngle = 190;
            var diffAngle = startAngle - endAngle;
            var akkuAngle = diffAngle * akku/100;
            var radius = scrWidth / 2 - penWidth;
    
    
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    
            //Continuous Arc - on the left side
            dc.setColor(Graphics.COLOR_DK_GRAY, Graphics.COLOR_TRANSPARENT);
            dc.drawArc(scrWidth / 2, scrHeight / 2, radius, Graphics.ARC_CLOCKWISE, startAngle, endAngle);
            dc.setColor(Graphics.COLOR_GREEN, Graphics.COLOR_TRANSPARENT);
            dc.drawArc(scrWidth / 2, scrHeight / 2, radius, Graphics.ARC_CLOCKWISE, startAngle, startAngle - akkuAngle);
            dc.drawText(scrWidth / 2, scrHeight / 2 - 20, Graphics.FONT_MEDIUM, akku.format("%0d") + " %", textCenter);
            dc.setPenWidth(penWidth);
    
            //simulating Segments 
            //Black Separators
            dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);
            var ang = startAngle;
            dc.setPenWidth(penWidth + 2);
            for(var i = 0; i < 4; i++) {
                dc.drawArc(scrWidth/2, scrHeight / 2, radius, Graphics.ARC_CLOCKWISE, ang - diffAngle/5 + 1, ang - diffAngle/5 - 1);
                ang -= diffAngle / 5 ;
            }        
    
    
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            //Segments - on the right side
            dc.setPenWidth(penWidth);
            startAngle = 300;
            endAngle = 350;
            diffAngle = endAngle - startAngle;
            ang = startAngle;
    
            for(var i = 0; i < 5; i++) {
                if ( akku > ( i * 20 ) ) {
                    dc.setColor(Graphics.COLOR_GREEN, Graphics.COLOR_TRANSPARENT);
                } else {
                    dc.setColor(Graphics.COLOR_DK_GRAY, Graphics.COLOR_TRANSPARENT);
                }
                dc.drawArc(scrWidth/2, scrHeight/2, radius, Graphics.ARC_COUNTER_CLOCKWISE, ang, ang + diffAngle/5 - 2);
                ang += diffAngle / 5;
            }        
    

  • Hi, I have one last question about this topic.

    Is it possible to create and add a function so that the dc.drawArc element moves with each percent of battery reduction?

    Thanks

  • Line 11 in the code snippet above takes every percentage point of the battery change into account. Another question is whether you can also see this on the display. And that of course depends on the size of the charging arc. To make the change visible for each percentage point, the arc must be so large that with each percentage the angle change is so large that new pixels light up/go out.

  • So in that arc, in your code it's not possible to do that? My watch has a MIP display. I'm just wondering how to even do this and if it's possible. Thanks

  • Try this watch face.  The arc on the right is battery, 0-100%, and it changes color if the watch is charging, or when the battery is less than 20%.

    https://apps.garmin.com/apps/c051f37a-8fad-4907-b124-0112fe010c91

  • As I stated above: line 11 takes every percent into account. To get a „real existing“ angle difference for each percent, the arc has to be 100° at least. Then 100% SOC equals to 100°, 99% SOC equals to 99° - and so on. And the radius of the arc has to be that big, that with every change of % there is a change in lightning pixels.

    To make it more clear: for a percentage lightning bar for SOC, the bar has to be 100 pixels wide, to light up (or go out) for different pixels.

    BTW: In practical use, it is completely irrelevant whether the actual width of the arch changes with every percentage change. You wouldn't notice it anyway...

  • Showing a continuous decrease using segments makes no sense.
    For a continuous progression, an arc without interruptions would be selected.

    I understand where you’re coming from, but I’ll just point out that the very popular Crystal watchface has segmented arcs which can fill up continuously (depending on the metric.)

    It makes sense to me bc you kinda get to have your cake and eat it too (segments which indicate discrete progress towards a goal, but they fill up continuously so you also have a more granular sense of your progress.) I could argue that analog watches kind of have a similar design (there’s discrete ticks marks for the hours and minutes, but the hands move continuously.)

    Another example is the native HR zone gauge data field on Garmin watches. The gauge has 5 discrete sections (one for each zone), but the arrow moves continuously as your HR changes. That way you can see which discrete zone you’re in and also (roughly) where you are within that zone.