8
8
getCategoriesArray ,
9
9
addCategory ,
10
10
} from "./db.js" ;
11
- import QuickChart from "quickchart-js" ;
11
+ import { ChartJSNodeCanvas } from "chartjs-node-canvas" ; // Import Chart.js
12
12
13
13
const { App, SocketModeReceiver } = pkg ;
14
14
dotenv . config ( ) ;
@@ -20,6 +20,14 @@ const app = new App({
20
20
} ) ,
21
21
} ) ;
22
22
23
+ // Set up the ChartJSNodeCanvas instance
24
+ const chartWidth = 800 ;
25
+ const chartHeight = 400 ;
26
+ const chartJSNodeCanvas = new ChartJSNodeCanvas ( {
27
+ width : chartWidth ,
28
+ height : chartHeight ,
29
+ } ) ;
30
+
23
31
app . command ( "/addcategory" , async ( { command, ack, respond } ) => {
24
32
await ack ( ) ; // Acknowledge the command
25
33
@@ -95,7 +103,6 @@ app.event("message", async ({ event, client }) => {
95
103
}
96
104
} ) ;
97
105
98
-
99
106
// Listen for when the user clicks the dropdown and fetch categories
100
107
app . options ( / c a t e g o r y _ s e l e c t - .* / , async ( { options, ack } ) => {
101
108
try {
@@ -133,7 +140,7 @@ app.options(/category_select-.*/, async ({ options, ack }) => {
133
140
} ) ;
134
141
135
142
// Listen for the interaction from the dropdown menu
136
- app . action ( / c a t e g o r y _ s e l e c t - .* / , async ( { body, ack, say } ) => {
143
+ app . action ( / c a t e g o r y _ s e l e c t - .* / , async ( { body, ack } ) => {
137
144
// Acknowledge the action
138
145
await ack ( ) ;
139
146
console . log ( "body" , body ) ;
@@ -156,7 +163,6 @@ app.command("/inc_stats", async ({ ack, body, client }) => {
156
163
const dbResponse = await getIncs ( numberOfDays ) ;
157
164
158
165
const totalIncs = dbResponse . rows . length ;
159
-
160
166
161
167
const chartUrlByWeek = await generateIncByWeekChart ( numberOfDays ) ;
162
168
const chartUrlByCategory = await generateIncByCategoryChart ( numberOfDays ) ;
@@ -184,7 +190,7 @@ app.command("/inc_stats", async ({ ack, body, client }) => {
184
190
{
185
191
type : "image" ,
186
192
image_url : chartUrlByCategory ,
187
- alt_text : "Incidents per Week " ,
193
+ alt_text : "Incidents per Category " ,
188
194
} ,
189
195
{
190
196
type : "image" ,
@@ -213,9 +219,8 @@ async function generateIncByWeekChart(numberOfDays) {
213
219
) ;
214
220
const data = incNumberByWeek . rows . map ( ( row ) => parseInt ( row . count , 10 ) ) ;
215
221
216
- // Generate the bar chart URL using QuickChart
217
- const chart = new QuickChart ( ) ;
218
- chart . setConfig ( {
222
+ // Create the chart configuration
223
+ const chartConfig = {
219
224
type : "line" ,
220
225
data : {
221
226
labels : labels ,
@@ -236,11 +241,20 @@ async function generateIncByWeekChart(numberOfDays) {
236
241
} ,
237
242
} ,
238
243
} ,
244
+ } ;
245
+
246
+
247
+ // Render the chart and get the image as JPEG
248
+ const imageBuffer = await chartJSNodeCanvas . renderToBuffer ( chartConfig , {
249
+ format : 'jpeg' , // Change format to JPEG
250
+ width : 400 , // Set width
251
+ height : 200 , // Set height
252
+ quality : 0.8 , // Set quality (0 to 1)
239
253
} ) ;
240
- // Increase chart size
241
- chart . setWidth ( 400 ) ;
242
- chart . setHeight ( 200 ) ;
243
- return chart . getShortUrl ( ) ;
254
+ // Convert the image buffer to a base64 string
255
+ const imageBase64 = imageBuffer . toString ( 'base64' ) ;
256
+ // Return the URL for Slack (using a data URL)
257
+ return `data:image/png;base64, ${ imageBase64 } ` ;
244
258
}
245
259
246
260
async function generateIncByCategoryChart ( numberOfDays ) {
@@ -250,9 +264,8 @@ async function generateIncByCategoryChart(numberOfDays) {
250
264
const labels = sortedCategories . map ( ( row ) => row . category ) ;
251
265
const data = sortedCategories . map ( ( row ) => parseInt ( row . count , 10 ) ) ;
252
266
253
- // Generate the bar chart URL using QuickChart
254
- const chart = new QuickChart ( ) ;
255
- chart . setConfig ( {
267
+ // Create the chart configuration
268
+ const chartConfig = {
256
269
type : "bar" ,
257
270
data : {
258
271
labels : labels ,
@@ -268,23 +281,30 @@ async function generateIncByCategoryChart(numberOfDays) {
268
281
} ,
269
282
options : {
270
283
scales : {
271
- xAxes : {
284
+ x : {
272
285
ticks : {
273
- max : labels . length , // Limit the number of labels to show
286
+ autoSkip : false , // Show all labels
287
+ maxTicksLimit : labels . length ,
274
288
} ,
275
289
} ,
276
- yAxes : {
277
- ticks : {
278
- beginAtZero : true , // Start the y-axis at 0
279
- stepSize : 1 , // Set the step size to 1
280
- }
290
+ y : {
291
+ beginAtZero : true ,
292
+ min : 0 ,
293
+ stepSize : 1 ,
281
294
} ,
282
295
} ,
283
296
} ,
297
+ } ;
298
+
299
+ // Render the chart and get the image as JPEG
300
+ const imageBuffer = await chartJSNodeCanvas . renderToBuffer ( chartConfig , {
301
+ format : 'jpeg' , // Change format to JPEG
302
+ width : 400 , // Set width
303
+ height : 200 , // Set height
304
+ quality : 0.8 , // Set quality (0 to 1)
284
305
} ) ;
285
-
286
- // Increase chart size
287
- chart . setWidth ( 400 ) ;
288
- chart . setHeight ( 200 ) ;
289
- return chart . getShortUrl ( ) ;
306
+ // Convert the image buffer to a base64 string
307
+ const imageBase64 = imageBuffer . toString ( 'base64' ) ;
308
+ // Return the URL for Slack (using a data URL)
309
+ return `data:image/png;base64,${ imageBase64 } ` ;
290
310
}
0 commit comments