Widget Examples

I created a widget to show nutritional macronutrients, both with a progress bar and values.
I created a shortcut that adds these values to Data Jar and saves it as a dictionary. You will then access the file via the file bookmarks in settings of Scriptable. You can use whatever food logger you wish as the shortcut pulls from HealthKit.

Thanks to @egamez for creating the weather widget which allowed me to learn about drawContext() and how he set up some of the functions was extremely helpful.
Here is the code:


let fm = FileManager.iCloud()
//let dir = fm.bookmarkedPath("Macros")

//Set up a bookmarked path in settings
let dir = fm.bookmarkedPath("macros.json")
let item = JSON.parse(fm.readString(dir))




const backgroundColor = new Color("#1C1C1E", 1)


let drawContext = new DrawContext();

drawContext.size = new Size(600, 400)
drawContext.opaque = false
    
let w = new ListWidget()
w.backgroundColor = backgroundColor
w.setPadding(10, 10, 10, 10)

  
let row = w.addStack()
let fatsImg = SFSymbol.named("flame.fill")


let fatsTotal = item.fats
let proteinTotal = item.protein
let carbsTotal = item.carbs
let calTotal = item.calories
let waterTotal = item.water
let workoutType = item.workout_type
let activeEnergy = item.active_energy
console.log(item)

// convert to percentage

let fatsPerent = ((fatsTotal * 4)/calTotal) * 100
let proteinPerent = ((proteinTotal * 4)/calTotal) * 100
let carbsPerent = ((carbsTotal * 4)/calTotal) * 100


let fatsY = 100 + (400 * (fatsPerent/100))
let proteinY = 200 - (130 * (proteinPerent/100))
let carbY = 200 - (130 * (carbsPerent/100))





// bar length

let x = 200
let length = 200



let carbStr = "Carbohydrates"
let proteinStr = "Protein"
let fatStr = "Fats"
let calStr = "Calories"
let waterStr = "Water"


// protein progress bar
drawText(proteinStr, 18, strX(proteinStr), 96, Color.white())

drawProgerss(x, 110, x + length, 110, 25, Color.red(),backgroundColor, (x -10) +(length)*(proteinPerent/100) )

drawText(`${proteinPerent.toFixed(2)} %`, 18, x + length + 20, 96, Color.white())

// carbs progress bar
drawText("Carbohydrates", 18, 50, 132, Color.white())
drawProgerss(x, 145, x + length, 145, 25, Color.blue(), backgroundColor,(x - 10) +(length)*(carbsPerent/100) )

drawText(`${carbsPerent.toFixed(2)} %`, 18, x + length + 20, 135, Color.white())

// fats progress bar

drawText("Fats", 18, 140, 170, Color.white())

drawProgerss(x, 180, x + length, 180, 25, Color.orange(), backgroundColor,(x - 10) +(length)*(fatsPerent/100) )

drawText(`${fatsPerent.toFixed(2)} %`, 18, x + length + 20, 170, Color.white())


// calories / burned text

drawText("Calories", 14, 40, 225, Color.white())


drawText(`${calTotal.toFixed(2)} kCal`, 14, 40, 245, Color.white())

drawText("Calories Burned", 14, 40, 275, Color.white())

drawText(`${activeEnergy}`, 14, 40, 295, Color.white())


// water / fats text

drawText("Water", 14, 240, 225, Color.white())


drawText(`${waterTotal.toFixed(2)} oz`, 14,240, 245, Color.white())

drawText("Fats", 14, 240, 275, Color.white())


drawText(`${fatsTotal.toFixed(2)} grams`, 14,240, 295, Color.white())


// carb / protein text

drawText("Carbohydrates", 14, 440, 225, Color.white())


drawText(`${carbsTotal.toFixed(2)} grams`, 14,440, 245, Color.white())

drawText("Protein", 14, 440, 275, Color.white())


drawText(`${proteinTotal.toFixed(2)} grams`, 14,440, 295, Color.white())



// line seperator 
drawLine(10, 210, 590, 210, 2, Color.orange())


w.backgroundImage = drawContext.getImage()
w.backgroundImage.size = new Size(600, 200)


w.presentMedium()

// w.presentLarge()


// functions

function drawText(text, fontSize, x, y, color = Color.black()){
  drawContext.setFont(Font.boldSystemFont(fontSize))
  drawContext.setTextColor(color)
  drawContext.drawText(new String(text).toString(), new Point(x, y))
}

function drawLine(x1, y1, x2, y2, width, color){
  const path = new Path()
  path.move(new Point(x1, y1))
  path.addLine(new Point(x2, y2))
  drawContext.addPath(path)
  drawContext.setStrokeColor(color)
  drawContext.setLineWidth(width)
  drawContext.strokePath()
}

function drawProgerss(x1,y1,x2,y2, width, color, indicatorColor, iX){
  
  const path = new Path()
  path.move(new Point(x1, y1))
  path.addLine(new Point(x2, y2))
  drawContext.addPath(path)
  drawContext.setStrokeColor(color)
  drawContext.setLineWidth(width)
  drawContext.strokePath()
  
  // left end of line
  drawContext.setFillColor(color)
drawContext.fillEllipse(new Rect(x1 - 10, y1 - 12 , width - 1, width - 1))
// right end line
drawContext.fillEllipse(new Rect(x2 - 10, y1 - 12, width - 1, width - 1))
  
  
// progress

  drawContext.setFillColor(indicatorColor)
drawContext.fillEllipse(new Rect(iX, y1 - 11, width - 3, width - 3))
      
}


function strX(string){
  
  console.log(x - (carbStr.length*10.77) - 10)
  
  let stringX = x - (string.length * 10.77) - 10
  
  return stringX
  
}

7 Likes