Graph and image display

Hi Gents,

I'd say I'm something like 80% done with my project.

I'd need your input on these two last parts : 

  1. I would like to be able to display a water level graph depending on the tidal data I retreive, such as this one : http://maree.info/125

         is there a tool to do so in the Garmin API? If not, is there a known API I could use?

       2. I would like to diplay an image on the watch face. This image will change depending on a value I retrieve from a webrequest() call. Would you have some tips on where to start?

Cheers,

Nico

  • And if you just skip bitmaps and resources and draw your own arrow, you free up memory of the lookup and bitmap, and can draw at any angle.  The basic logic for that is in the analog sample in the SDK for when it's drawing hands

    Yes, I agree with that.

    Sorry, I should've made it clear that if you had to do some sort of bitmap lookup, that would probably be the most efficient way to do it, in case the OP wanted to do it some other situation. I omitted the disclaimer that your solution is clearly the better solution in this case.

    I used an example which relates to this situation only because I didn't want to make up another example.

  • This is actually an example for people looking to save memory in an app.  Sometime an initial design decision can have a good sized impact, but it isn't something that's thought about when you're 2k under the limit for an app.  That's why you need to think about memory impact starting with the 1st line of code written, and  there is a learning curve that might not be seen until you do a few apps.

    I'm using a WF right now that's 12.1k, that will run on most devices, uses onPartialUpdate to update the display, works on the venu devices with Always on and has a background Service that gets data from a BLE sensor.  Preserving memory was important for every step and not something left for the end..

  • Once again, I agree with your approach to this situation and your comments regarding memory.

    The only purpose of my comment was to give an example of how you could try to "efficiently" look up one symbol out of many, if you had to. Just so the OP would have an example if they ever needed it in a different situation.

    I suppose I should've just made up an example which had no relation to specific details of this question.

  • Hi FlowState,

    I get your point. But actually, event if I could do it differently and more efficiently, this is the path I'd like to take.

    Still I'm having some trouble to make it work.

    var WindDirectionDisplayRounded = 22.5;
    
    
    
    class MyWatchFaceView extends WatchUi.WatchFace {
    var background;
    var Arrow0;
    var Arrow22;
    var Arrow45;
    var Arrow67;
    var Arrow90;
    var Arrow112;
    var Arrow135;
    var Arrow157;
    var Arrow180;
    var Arrow202;
    var Arrow225;
    var Arrow247;
    var Arrow270;
    var Arrow292;
    var Arrow315;
    var Arrow337;
    
    ...
    
    
    
    
    function initialize() {
    WatchFace.initialize();
    background = WatchUi.loadResource(Rez.Drawables.Background);
    Arrow0 = WatchUi.loadResource(Rez.Drawables.Arrow0);
    Arrow22 = WatchUi.loadResource(Rez.Drawables.Arrow22);
    Arrow45 = WatchUi.loadResource(Rez.Drawables.Arrow45);
    Arrow67 = WatchUi.loadResource(Rez.Drawables.Arrow67);
    Arrow90 = WatchUi.loadResource(Rez.Drawables.Arrow90);
    Arrow112 = WatchUi.loadResource(Rez.Drawables.Arrow112);
    Arrow135 = WatchUi.loadResource(Rez.Drawables.Arrow135);
    Arrow157 = WatchUi.loadResource(Rez.Drawables.Arrow157);
    Arrow180 = WatchUi.loadResource(Rez.Drawables.Arrow180);
    Arrow202 = WatchUi.loadResource(Rez.Drawables.Arrow202);
    Arrow225 = WatchUi.loadResource(Rez.Drawables.Arrow225);
    Arrow247 = WatchUi.loadResource(Rez.Drawables.Arrow247);
    Arrow270 = WatchUi.loadResource(Rez.Drawables.Arrow270);
    Arrow292 = WatchUi.loadResource(Rez.Drawables.Arrow292);
    Arrow315 = WatchUi.loadResource(Rez.Drawables.Arrow315);
    Arrow337 = WatchUi.loadResource(Rez.Drawables.Arrow337);
    
    ...
    
    
    
     function onUpdate(dc as Dc) as Void {
    
    var ArrowPosX = 156;
    var ArrowPosY = 68;
    var arrowSymbols = [
    :Arrow0,
    :Arrow22,
    :Arrow45,
    :Arrow67,
    :Arrow90,
    :Arrow112,
    :Arrow135,
    :Arrow157,
    :Arrow180,
    :Arrow202,
    :Arrow225,
    :Arrow247,
    :Arrow270,
    :Arrow315,
    :Arrow335,
    ];
    
    var bitmapSymbol = arrowSymbols[(WindDirectionDisplayRounded / 22.5).toNumber()];
    Sys.println((WindDirectionDisplayRounded / 22.5).toNumber());
    Sys.println(bitmapSymbol);
    
    dc.drawBitmap(ArrowPosX, ArrowPosY, bitmapSymbol);

    This throws an Hundled Exception 

    Exception: UnexpectedTypeException: Expected an object of type WatchUi.BitmapResource

    I don't really get why since my Arrow variables are declared and initialized and referenced as drawables in the XML file.

    Any idea?

    EDIT : I call the  dc.drawBitmap function right after the dc.drawBitmap(0,0,background); call.

  • What's the range of possible values for WindDirectionDisplayRounded? Is it 0 to 359? If it's 0 to 360, then that will be an issue. Or are you testing with WindDirectionDisplayRounded = 22.5 as in the above example code?

    When it crashes, what's the value printed by Sys.println((WindDirectionDisplayRounded / 22.5).toNumber())?

    Looks like you are missing an entry in the array for :Arrow292, which mean that you could go out of bounds on the array, even if WindDirectionDisplayRounded can never go over 359.

  • The other thing to note is that toNumber() will truncate (round down). e.g. 1.75 => 1.

    If you want to round to the nearest integer (so 1.5 rounds to 2), then you need to use Math.round(). You may also want to handle the case where the wind direction is greater or equal to 360.

    So a more comprehensive solution could be:

    var arrayIndex = Math.round(WindDirectionDisplayRounded / 22.5).toNumber();
    // handle the case of WindDirectionDisplayRounded >= 360
    // (but still assume that WindDirectionDisplayRounded >= 0)
    if (arrayIndex >= arrowSymbols.size()) { 
        arrayIndex = 0;
    }
    var bitmapSymbol = arrowSymbols[arrayIndex];

  • Sys.println((WindDirectionDisplayRounded / 22.5).toNumber()) displays 10   and WindDirectionDisplayRounded is 225

    WindDirectionDisplayRounded goes from 0 to 337 with increments of 22.5. It never goes to 360 as I make sure if(WindDirectionDisplayRounded == 360){ WindDirectionDisplayRounded = 0;}

    I just spot I missed the :Arrow337 entry in the symbol, but I still get this exception.

    WindDirectionDisplayRounded is initialised at 22.5, and its value get changed later on (by increments of 22.5).

  • Since you've already loaded the bitmaps into vars in initialize, I think you want to store the vars in the array, not the symbols.

    var arrowBitmaps = [
        Arrow0,
        Arrow22,
        Arrow45,
        Arrow67,
        Arrow90,
        Arrow112,
        Arrow135,
        Arrow157,
        Arrow180,
        Arrow202,
        Arrow225,
        Arrow247,
        Arrow270,
        Arrow292,
        Arrow315,
        Arrow337
    ];
    
    var arrayIndex = Math.round(WindDirectionDisplayRounded / 22.5).toNumber();
    var bitmap = arrowBitmaps[arrayIndex];
    dc.drawBitmap(ArrowPosX, ArrowPosY, bitmap);