summaryrefslogtreecommitdiff
path: root/api/static/js
diff options
context:
space:
mode:
authorCaptainJack2491 <jayrupnakawala@gmail.com>2026-03-09 20:35:34 +0000
committerCaptainJack2491 <jayrupnakawala@gmail.com>2026-03-09 20:35:34 +0000
commitf19aa5de3e3f1c3c0b9ce90913588b9e956d4156 (patch)
tree227e8b437548c98565fdb344fe8db8e4a97b3235 /api/static/js
parent17acb7a802d6d6f844c51dca5f2f171e360eca8d (diff)
feat: add total token usage chart and update documentation
This commit: - Adds a 'Total Token Usage by Model' chart alongside the average token chart - Updates the web_gui_plan.md to reflect the removal of execution APIs and the addition of the new data visualization features.
Diffstat (limited to 'api/static/js')
-rw-r--r--api/static/js/components/results.js59
1 files changed, 55 insertions, 4 deletions
diff --git a/api/static/js/components/results.js b/api/static/js/components/results.js
index 9b530f4..b143fa3 100644
--- a/api/static/js/components/results.js
+++ b/api/static/js/components/results.js
@@ -231,7 +231,8 @@ export const results = {
}
if (cols.includes('model') && cols.includes('total_tokens')) {
- this.renderTokenUsageChart('Average Token Usage by Model', data);
+ this.renderAverageTokenUsageChart('Average Token Usage by Model', data);
+ this.renderTotalTokenUsageChart('Total Token Usage by Model', data);
}
if (ui.elements.interactiveCharts.innerHTML === '') {
@@ -239,7 +240,7 @@ export const results = {
}
},
- renderTokenUsageChart(title, data) {
+ renderAverageTokenUsageChart(title, data) {
const metrics = {}; // { model: { total: 0, count: 0, prompt: 0, completion: 0 } }
data.forEach(row => {
@@ -260,12 +261,12 @@ export const results = {
const datasets = [
{
- label: 'Prompt Tokens',
+ label: 'Avg Prompt Tokens',
data: labels.map(l => metrics[l].prompt / metrics[l].count),
backgroundColor: '#3b82f6',
},
{
- label: 'Completion Tokens',
+ label: 'Avg Completion Tokens',
data: labels.map(l => metrics[l].completion / metrics[l].count),
backgroundColor: '#10b981',
}
@@ -291,6 +292,56 @@ export const results = {
activeCharts.push(chart);
},
+ renderTotalTokenUsageChart(title, data) {
+ const metrics = {}; // { model: { prompt: 0, completion: 0 } }
+
+ data.forEach(row => {
+ const model = row.model || 'Unknown';
+ if (!row.total_tokens) return;
+
+ if (!metrics[model]) {
+ metrics[model] = { prompt: 0, completion: 0 };
+ }
+ metrics[model].prompt += row.prompt_tokens || 0;
+ metrics[model].completion += row.completion_tokens || 0;
+ });
+
+ const labels = Object.keys(metrics).sort();
+ if (labels.length === 0) return;
+
+ const datasets = [
+ {
+ label: 'Total Prompt Tokens',
+ data: labels.map(l => metrics[l].prompt),
+ backgroundColor: '#6366f1',
+ },
+ {
+ label: 'Total Completion Tokens',
+ data: labels.map(l => metrics[l].completion),
+ backgroundColor: '#f59e0b',
+ }
+ ];
+
+ const config = {
+ type: 'bar',
+ data: { labels, datasets },
+ options: {
+ ...this.getChartOptions(title),
+ scales: {
+ x: { stacked: true, ticks: { color: '#9ea0a6' }, grid: { color: '#2a2a2e' } },
+ y: { stacked: true, ticks: { color: '#9ea0a6' }, grid: { color: '#2a2a2e' } }
+ }
+ }
+ };
+
+ const canvasId = `chart-${Math.random().toString(36).substr(2, 9)}`;
+ this.createChartContainer(canvasId, config);
+
+ const ctx = document.getElementById(canvasId).getContext('2d');
+ const chart = new Chart(ctx, config);
+ activeCharts.push(chart);
+ },
+
renderDoughnutChart(title, data, column) {
const counts = {};
data.forEach(row => {