-
-
Save donfelipo/25e633b2d8d76af20ce0601af5b67562 to your computer and use it in GitHub Desktop.
Simple line chart class for https://scriptable.app π
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Variables used by Scriptable. | |
// These must be at the very top of the file. Do not edit. | |
// icon-color: orange; icon-glyph: magic; | |
class LineChart { | |
// LineChart by https://kevinkub.de/ | |
constructor(width, height, values) { | |
this.ctx = new DrawContext(); | |
this.ctx.size = new Size(width, height); | |
this.values = values; | |
} | |
_calculatePath() { | |
let maxValue = Math.max(...this.values); | |
let minValue = Math.min(...this.values); | |
let difference = maxValue - minValue; | |
let count = this.values.length; | |
let step = this.ctx.size.width / (count - 1); | |
let points = this.values.map((current, index, all) => { | |
let x = step*index; | |
let y = this.ctx.size.height - (current - minValue) / difference * this.ctx.size.height; | |
return new Point(x, y); | |
}); | |
return this._getSmoothPath(points); | |
} | |
_getSmoothPath(points) { | |
let path = new Path(); | |
path.move(new Point(0, this.ctx.size.height)); | |
path.addLine(points[0]); | |
for(let i = 0; i < points.length-1; i++) { | |
let xAvg = (points[i].x + points[i+1].x) / 2; | |
let yAvg = (points[i].y + points[i+1].y) / 2; | |
let avg = new Point(xAvg, yAvg); | |
let cp1 = new Point((xAvg + points[i].x) / 2, points[i].y); | |
let next = new Point(points[i+1].x, points[i+1].y); | |
let cp2 = new Point((xAvg + points[i+1].x) / 2, points[i+1].y); | |
path.addQuadCurve(avg, cp1); | |
path.addQuadCurve(next, cp2); | |
} | |
path.addLine(new Point(this.ctx.size.width, this.ctx.size.height)); | |
path.closeSubpath(); | |
return path; | |
} | |
configure(fn) { | |
let path = this._calculatePath(); | |
if(fn) { | |
fn(this.ctx, path); | |
} else { | |
this.ctx.addPath(path); | |
this.ctx.fillPath(path); | |
} | |
return this.ctx; | |
} | |
} | |
// Demo | |
let data = [20, 10, 15, 5, 10, 30, 20, 10, 10, 10, 20, 10]; | |
let widget = new ListWidget(); | |
let chart = new LineChart(700, 338, data).configure((ctx, path) => { | |
ctx.opaque = false; | |
ctx.setFillColor(new Color("888888", .5)); | |
ctx.addPath(path); | |
ctx.fillPath(path); | |
}).getImage(); | |
widget.addText("Hello Charts!"); | |
widget.addSpacer(); | |
let image = widget.addImage(chart); | |
Script.setWidget(widget); | |
if (!config.runsInWidget) { | |
await widget.presentSmall(); | |
} | |
Script.complete(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment