You are reading a single comment by @HughB and its replies. Click here to read the full conversation.
  • @Gordon - here's my code - have a play with it and let me know what you think.
    I'm enjoying the Health App a lot more since I have done this.

    function getSettings() {
      return require("Storage").readJSON("health.json­",1)||{};
    }
    
    function setSettings(s) {
      require("Storage").writeJSON("health.jso­n",s);
    }
    
    function menuMain() {
      swipe_enabled = false;
      E.showMenu({
        "":{title:"Health Tracking"},
        "< Back":()=>load(),
        "Step Counting":()=>menuStepCount(),
        "Movement":()=>menuMovement(),
        "Heart Rate":()=>menuHRM(),
        "Settings":()=>menuSettings()
      });
    }
    
    function menuSettings() {
      swipe_enabled = false;
      var s=getSettings();
      E.showMenu({
        "":{title:"Health Tracking"},
        "< Back":()=>menuMain(),
        "Heart Rt":{
          value : 0|s.hrm,
          min : 0, max : 2,
          format : v=>["Off","10 mins","Always"][v],
          onchange : v => { s.hrm=v;setSettings(s); }
        }
      });
    }
    
    function menuStepCount() {
      swipe_enabled = false;
      E.showMenu({
        "":{title:"Step Counting"},
        "< Back":()=>menuMain(),
        "per hour":()=>stepsPerHour(),
        "per day":()=>stepsPerDay()
      });
    }
    
    function menuMovement() {
      swipe_enabled = false;
      E.showMenu({
        "":{title:"Movement"},
        "< Back":()=>menuMain(),
        "per hour":()=>movementPerHour(),
        "per day":()=>movementPerDay(),
      });
    }
    
    function menuHRM() {
      swipe_enabled = false;
      E.showMenu({
        "":{title:"Heart Rate"},
        "< Back":()=>menuMain(),
        "per hour":()=>hrmPerHour(),
        "per day":()=>hrmPerDay(),
      });
    }
    
    
    function stepsPerHour() {
      E.showMessage("Loading...");
      var data = new Uint16Array(24);
      require("health").readDay(new Date(), h=>data[h.hr]+=h.steps);
      console.log(data);
      g.clear(1);
      Bangle.drawWidgets();
      g.reset();
      Bangle.setUI("updown", ()=>menuStepCount());
      barChart("HOUR", data);
    }
    
    function stepsPerDay() {
      E.showMessage("Loading...");
      var data = new Uint16Array(31);
      require("health").readDailySummaries(new­ Date(), h=>data[h.day]+=h.steps);
      console.log(data);
      g.clear(1);
      Bangle.drawWidgets();
      g.reset();
      Bangle.setUI("updown", ()=>menuStepCount());
      barChart("DAY", data);
    }
    
    function hrmPerHour() {
      E.showMessage("Loading...");
      var data = new Uint16Array(24);
      var cnt = new Uint8Array(23);
      require("health").readDay(new Date(), h=>{
        data[h.hr]+=h.bpm;
        if (h.bpm) cnt[h.hr]++;
      });
      data.forEach((d,i)=>data[i] = d/cnt[i]);
      g.clear(1);
      Bangle.drawWidgets();
      g.reset();
      Bangle.setUI("updown", ()=>menuHRM());
      barChart("HOUR", data);
    }
    
    function hrmPerDay() {
      E.showMessage("Loading...");
      var data = new Uint16Array(31);
      var cnt = new Uint8Array(31);
      require("health").readDailySummaries(new­ Date(), h=>{
        data[h.day]+=h.bpm;
        if (h.bpm) cnt[h.day]++;
      });
      data.forEach((d,i)=>data[i] = d/cnt[i]);
      g.clear(1);
      Bangle.drawWidgets();
      g.reset();
      Bangle.setUI("updown", ()=>menuHRM());
      barChart("DAY", data);
    }
    
    function movementPerHour() {
      E.showMessage("Loading...");
      var data = new Uint16Array(24);
      require("health").readDay(new Date(), h=>data[h.hr]+=h.movement);
      g.clear(1);
      Bangle.drawWidgets();
      g.reset();
      Bangle.setUI("updown", ()=>menuMovement());
      barChart("HOUR", data);
    }
    
    function movementPerDay() {
      E.showMessage("Loading...");
      var data = new Uint16Array(31);
      require("health").readDailySummaries(new­ Date(), h=>data[h.day]+=h.movement);
      g.clear(1);
      Bangle.drawWidgets();
      g.reset();
      Bangle.setUI("updown", ()=>menuMovement());
      barChart("DAY", data);
    }
    
    // Bar Chart Code
    
    const w = g.getWidth();
    const h = g.getHeight();
    
    // find the max value in the array, using a loop due to array size 
    function max(arr) {
      var m = -Infinity;
    
      for(var i=0; i< arr.length; i++)
        if(arr[i] > m) m = arr[i];
      return m;
    }
    
    // find the end of the data, the array might be for 31 days but only have 2 days in it
    function get_data_length(arr) {
      var nlen = arr.length;
      
      for(var i = arr.length - 1; i > 0 && arr[i] == 0;  i--)
        nlen--;
      
      return nlen;
    }
    
    var data_len;
    var chart_index;
    var chart_max_datum;
    var chart_label;
    var chart_data;
    var swipe_enabled = false;
    
    function barChart(label, dt) {
      data_len = get_data_length(dt);
      chart_index = Math.max(data_len - 5, -5);  // choose initial index that puts the last day on the end
      chart_max_datum = max(dt);                 // find highest bar, for scaling
      chart_label = label;
      chart_data = dt;
      drawBarChart();
      swipe_enabled = true;
    }
    
    function drawBarChart() {
      const bar_bot = 140;
      const bar_width = (w - 2) / 9;  // we want 9 bars, bar 5 in the centre
      var bar_top;
      var bar;
      
      g.setColor(g.theme.bg);
      g.fillRect(0,24,w,h);
      
      for (bar = 1; bar < 10; bar++) {
        if (bar == 5) {
          g.setFont('6x8', 2);
          g.setFontAlign(0,-1)
          g.setColor(g.theme.fg);
          g.drawString(chart_label + " " + (chart_index + bar -1) + "   " + chart_data[chart_index + bar - 1], g.getWidth()/2, 150);
          g.setColor("#00f");
        } else {
          g.setColor("#0ff");
        }
    
        // draw a fake 0 height bar if chart_index is outside the bounds of the array
        if ((chart_index + bar - 1) >= 0 && (chart_index + bar - 1) < data_len) 
          bar_top = bar_bot - 100 * (chart_data[chart_index + bar - 1]) / chart_max_datum;
        else
          bar_top = bar_bot;
    
        g.fillRect( 1 + (bar - 1)* bar_width, bar_bot, 1 + bar*bar_width, bar_top);
        g.setColor(g.theme.fg);
        g.drawRect( 1 + (bar - 1)* bar_width, bar_bot, 1 + bar*bar_width, bar_top);
      }
    }
    
    function next_bar() {
      chart_index = Math.min(data_len - 5, chart_index + 1);
    }
    
    function prev_bar() {
      chart_index = Math.max(-4, chart_index - 1);
    }
    
    Bangle.on('swipe', dir => {
      if (!swipe_enabled) return;
      if (dir == 1) prev_bar(); else next_bar();
      drawBarChart();
    });
    
    Bangle.loadWidgets();
    Bangle.drawWidgets();
    menuMain();
    
    
    
    
About

Avatar for HughB @HughB started