-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCircle.js
More file actions
127 lines (98 loc) · 3.07 KB
/
Circle.js
File metadata and controls
127 lines (98 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: deep-purple; icon-glyph: circle-notch;
const { ConfigStore } = importModule("Config Util");
/**
* Used to generate circular chart.
*
* @class Circle
*/
class Circle {
static #DEFAULT_CONFIG = {
size: 400,
steps: 180,
diameter: 350,
fill: false,
circleLineWidth: 40,
data: [
{
color: Color.gray(),
percentage: 100
}
]
};
#configStore = new ConfigStore();
/**
* Creates an instance of Circle.
*
* @param {Object} userConfig circle configuration
* @memberof Circle
*/
constructor(userConfig) {
this.#configStore.setConfig(Circle.#DEFAULT_CONFIG);
this.#configStore.overrideConfig(userConfig);
}
/**
* Used to generate image with circular chart.
*
* @return {Image} chart image
* @memberof Circle
*/
image() {
const context = new DrawContext();
context.opaque = false;
const size = this.#configStore.get("size");
context.size = new Size(size, size);
context.setLineWidth(this.#configStore.get("circleLineWidth"));
const circleData = [{
color: null,
percentage: 0
}].concat(this.#configStore.get("data"));
for (let i = 0; i + 1 < circleData.length; i++) {
const from = circleData[i];
const to = circleData[i + 1];
const segment = this.#getSegment(
from.percentage,
to.percentage
);
context.setFillColor(to.color);
context.setStrokeColor(to.color);
context.addPath(segment);
if (this.#configStore.get("fill")) {
context.fillPath();
} else {
context.strokePath();
};
}
return context.getImage();
}
/**
* Used to generate chart segment.
*
* @param {Number} from starting percentage
* @param {Number} to ending percentage
* @return {Path} segment
* @memberof Circle
*/
#getSegment(from, to) {
const step = Math.PI * 2 / this.#configStore.get("steps");
const points = [];
const size = this.#configStore.get("size") + 1;
const origin = size / 2;
const radius = this.#configStore.get("diameter") / 2;
if (this.#configStore.get("fill")) {
points.push(new Point(origin, origin));
}
for (let theta = Math.PI * (from * 2 / 100); theta < Math.PI * (to * 2 / 100); theta += step) {
const x = origin + Math.sin(theta) * radius;
const y = origin - Math.cos(theta) * radius;
points.push(new Point(x, y));
}
const path = new Path();
path.addLines(points);
return path;
}
};
module.exports = {
Circle
};