08-08-2020 15:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-08-2020 15:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
I wanted to share something I put together that allows us to create a line chart from data on the watch itself without using a companion app. You can use it to track heartbeat, pauses, exercise, button presses, etc. You'd just need to add a redraw function when you add new data. This graph will auto scale. You can add as many data points for as many line segments you put in the index.gui.
Here's what the barebones graph looks like on your watchface as you add data in:
What other creative ways are there to get around the current limitations to create graphs and charts on the fitbit and do you have any suggestions to make the graph better?
Here is the index.gui:
<svg>
<line id="1" class="line" />
<line id="2" class="line" />
<line id="3" class="line" />
<line id="4" class="line" />
<line id="5" class="line" />
<line id="6" class="line" />
<line id="7" class="line" />
<line id="8" class="line" />
<line id="9" class="line" />
<line id="10" class="line" />
<line id="11" class="line" />
<line id="12" class="line" />
<line id="13" class="line" />
<line id="14" class="line" />
<line id="15" class="line" />
<line id="16" class="line" />
<line id="17" class="line" />
<line id="18" class="line" />
<line id="19" class="line" />
<line id="20" class="line" />
</svg>
And here is the index.js code
import document from "document";
let lines = [];
let xOffset = 25;
let yOffset = 25;
let data = [
1.1, 1.2, 1.45, 2.3, 3.56,
4, 4.2, 4.5, 5.3, 5.4,
5.3, 4.9, 3.4, 3.1, 2.9];
let len = data.length;
let xAxisInt = (325-xOffset*2)/len;
let dataMin = min(data);
let dataMax = max(data);
setup(data);
for(let i = 0; i < data.length-1; i++){
lines[i].style.display = "inline";
lines[i+1].style.display = "inline";
lines[i].x1 = xOffset+i*xAxisInt;
lines[i].x2 = xOffset+(i+1)*xAxisInt;
lines[i].y1 = mapY(data[i], dataMin, dataMax, 275,25);
lines[i].y2 = mapY(data[i+1], dataMin, dataMax, 275,25);
}
function setup(data){
for (let i = 0; i < data.length; i++){
let index = (i+1).toString();
lines.push(document.getElementById(index));
lines[i].style.display = "none";
lines[i].fill="red";
}
}
function max(array){
let max = -Infinity;
for(let i = 0; i < array.length;i++){
if(array[i]>max){
max = array[i]
}
}
return max
}
function min(array){
let min = Infinity;
for(let i = 0; i < array.length;i++){
if(array[i]<min){
min = array[i]
}
}
return min
}
function mapY(y, in_min, in_max, out_min, out_max) {
return (y - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
And finally heres the styles.css
.line {
fill: grey;
stroke-width: 5;
}
08-08-2020 15:13
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


08-08-2020 15:13
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I think that will be very useful for a lot of people.
I've developed a few clockfaces and apps that display bar charts using a similar method. Here's a free one that can be zoomed and panned, with labels on the axes. The screenshots are a bit misleading because they're based on fake data.
Gondwana Software

08-08-2020 15:26
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-08-2020 15:26
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Interesting, I'm assuming instead of blank line tags, you used black rect tags and then calculate the y and height values based on the data. I really like the ability to switch from one metric to another.

08-08-2020 15:30
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


08-08-2020 15:30
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
That's right.
You might also consider getElementsByClassName, which can make it quicker to scoop up all the segments in one go. It may not help much in your case, though.
Gondwana Software

09-03-2020 12:46
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

09-03-2020 12:46
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Thanks for this! My standard clock face since I got my versa has been this heart rate monitor
But it has gained some visual glitches since the 4.2 firmware update (semi-transparent elements are now rendering as fully opaque).
I'm fairly sure the developer has abandoned Fitbit development so I'm going to have a go at creating something similar myself. Your example will help get me started.

09-04-2020 22:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

09-04-2020 22:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
Cool. Here is what my graphs look like on the Sentinel clockface.
The graph area is actually a button and hitting it cycles through 30min (6 points), 1hr (12 points), 2hr(24 points) graphs of blood-glucose data for up to 3 people (so up to 72 points and the associated 69 lines. Plus I have 6 floating numbers per person. The graph normalizes to the size of the button area. It took a while for me to get it right.
