promptfoo 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/README.md +1 -1
  2. package/dist/package.json +4 -4
  3. package/dist/src/assertions.d.ts.map +1 -1
  4. package/dist/src/assertions.js +5 -0
  5. package/dist/src/assertions.js.map +1 -1
  6. package/dist/src/evaluator.js +1 -1
  7. package/dist/src/evaluator.js.map +1 -1
  8. package/dist/src/index.d.ts +1 -5
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +1 -1
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/matchers.d.ts +3 -2
  13. package/dist/src/matchers.d.ts.map +1 -1
  14. package/dist/src/matchers.js +37 -9
  15. package/dist/src/matchers.js.map +1 -1
  16. package/dist/src/providers/anthropic.d.ts +5 -3
  17. package/dist/src/providers/anthropic.d.ts.map +1 -1
  18. package/dist/src/providers/anthropic.js +8 -10
  19. package/dist/src/providers/anthropic.js.map +1 -1
  20. package/dist/src/providers/azureopenai.d.ts +9 -8
  21. package/dist/src/providers/azureopenai.d.ts.map +1 -1
  22. package/dist/src/providers/azureopenai.js +33 -36
  23. package/dist/src/providers/azureopenai.js.map +1 -1
  24. package/dist/src/providers/openai.d.ts +12 -12
  25. package/dist/src/providers/openai.d.ts.map +1 -1
  26. package/dist/src/providers/openai.js +54 -65
  27. package/dist/src/providers/openai.js.map +1 -1
  28. package/dist/src/providers/replicate.d.ts +4 -2
  29. package/dist/src/providers/replicate.d.ts.map +1 -1
  30. package/dist/src/providers/replicate.js +10 -8
  31. package/dist/src/providers/replicate.js.map +1 -1
  32. package/dist/src/providers/webhook.d.ts +9 -0
  33. package/dist/src/providers/webhook.d.ts.map +1 -0
  34. package/dist/src/providers/webhook.js +54 -0
  35. package/dist/src/providers/webhook.js.map +1 -0
  36. package/dist/src/providers.d.ts +1 -1
  37. package/dist/src/providers.d.ts.map +1 -1
  38. package/dist/src/providers.js +36 -28
  39. package/dist/src/providers.js.map +1 -1
  40. package/dist/src/suggestions.d.ts.map +1 -1
  41. package/dist/src/suggestions.js +1 -3
  42. package/dist/src/suggestions.js.map +1 -1
  43. package/dist/src/types.d.ts +7 -1
  44. package/dist/src/types.d.ts.map +1 -1
  45. package/dist/src/util.js +1 -1
  46. package/dist/src/util.js.map +1 -1
  47. package/dist/src/web/nextui/404/index.html +1 -1
  48. package/dist/src/web/nextui/404.html +1 -1
  49. package/dist/src/web/nextui/_next/static/Bl3o5lF4ON7Fjki46lPhr/_buildManifest.js +1 -0
  50. package/dist/src/web/nextui/_next/static/chunks/226-7bbb6c98a19542fd.js +37 -0
  51. package/dist/src/web/nextui/_next/static/chunks/249-ea9c0f034888ccff.js +125 -0
  52. package/dist/src/web/nextui/_next/static/chunks/339-501c32916b785ef1.js +1 -0
  53. package/dist/src/web/nextui/_next/static/chunks/365-e426ea5bc7e815fc.js +8 -0
  54. package/dist/src/web/nextui/_next/static/chunks/396-0a51429a01e24cdd.js +1 -0
  55. package/dist/src/web/nextui/_next/static/chunks/596-297f7ff4a0436e87.js +25 -0
  56. package/dist/src/web/nextui/_next/static/chunks/613-572c22424de64659.js +1 -0
  57. package/dist/src/web/nextui/_next/static/chunks/706-ae1d3352d28419e9.js +9 -0
  58. package/dist/src/web/nextui/_next/static/chunks/891-7035926a62c1c4e0.js +1 -0
  59. package/dist/src/web/nextui/_next/static/chunks/app/eval/[id]/not-found-366629541fd598e9.js +1 -0
  60. package/dist/src/web/nextui/_next/static/chunks/app/eval/[id]/page-319d2ee38d37574e.js +1 -0
  61. package/dist/src/web/nextui/_next/static/chunks/app/eval/page-a6b1ff91723b7beb.js +1 -0
  62. package/dist/src/web/nextui/_next/static/chunks/app/layout-024c4adc71c9feb0.js +1 -0
  63. package/dist/src/web/nextui/_next/static/chunks/app/page-1ae60660130041b2.js +1 -0
  64. package/dist/src/web/nextui/_next/static/chunks/app/setup/page-6ef16148040bf4f4.js +1 -0
  65. package/dist/src/web/nextui/_next/static/chunks/{ca377847-cb6ae6a6a073aebb.js → ca377847-26b462611379a4f7.js} +3 -3
  66. package/dist/src/web/nextui/_next/static/chunks/{fd9d1056-ac777be631f5a9e9.js → fd9d1056-fba4b53a2f01213b.js} +1 -1
  67. package/dist/src/web/nextui/_next/static/chunks/framework-8883d1e9be70c3da.js +25 -0
  68. package/dist/src/web/nextui/_next/static/chunks/main-8ea85465d428ecfe.js +1 -0
  69. package/dist/src/web/nextui/_next/static/chunks/main-app-581ccf0003955b21.js +1 -0
  70. package/dist/src/web/nextui/_next/static/chunks/pages/_app-52924524f99094ab.js +1 -0
  71. package/dist/src/web/nextui/_next/static/chunks/pages/_error-c92d5c4bb2b49926.js +1 -0
  72. package/dist/src/web/nextui/_next/static/chunks/webpack-55c264ce2fd85eb7.js +1 -0
  73. package/dist/src/web/nextui/_next/static/css/4d399fceacd06992.css +1 -0
  74. package/dist/src/web/nextui/eval/index.html +1 -1
  75. package/dist/src/web/nextui/eval/index.txt +6 -6
  76. package/dist/src/web/nextui/index.html +1 -1
  77. package/dist/src/web/nextui/index.txt +5 -5
  78. package/dist/src/web/nextui/setup/index.html +27 -1
  79. package/dist/src/web/nextui/setup/index.txt +9 -9
  80. package/dist/src/web/server.d.ts.map +1 -1
  81. package/dist/src/web/server.js +9 -5
  82. package/dist/src/web/server.js.map +1 -1
  83. package/package.json +4 -4
  84. package/dist/src/web/nextui/_next/static/US6gOx8LHTX_Hzm9aYNrC/_buildManifest.js +0 -1
  85. package/dist/src/web/nextui/_next/static/chunks/339-4fc8a80fa840e771.js +0 -1
  86. package/dist/src/web/nextui/_next/static/chunks/373-8a280796c0f2d1af.js +0 -1
  87. package/dist/src/web/nextui/_next/static/chunks/583-125d32af505e9bc4.js +0 -1
  88. package/dist/src/web/nextui/_next/static/chunks/596-07e4a23a5c6cdf04.js +0 -25
  89. package/dist/src/web/nextui/_next/static/chunks/658-a62210d07dc4dcb6.js +0 -15
  90. package/dist/src/web/nextui/_next/static/chunks/707-699cbd84b259c37b.js +0 -37
  91. package/dist/src/web/nextui/_next/static/chunks/858-ceb6fa22e614492b.js +0 -125
  92. package/dist/src/web/nextui/_next/static/chunks/891-3000ea7c0a292558.js +0 -1
  93. package/dist/src/web/nextui/_next/static/chunks/app/eval/[id]/not-found-50e40614fa05600e.js +0 -1
  94. package/dist/src/web/nextui/_next/static/chunks/app/eval/[id]/page-c19c44ed1b2dfb58.js +0 -1
  95. package/dist/src/web/nextui/_next/static/chunks/app/eval/page-d4a1813b2f8c4532.js +0 -1
  96. package/dist/src/web/nextui/_next/static/chunks/app/layout-664a8d716d2d24b1.js +0 -1
  97. package/dist/src/web/nextui/_next/static/chunks/app/page-1f8ef6a00a2355f0.js +0 -1
  98. package/dist/src/web/nextui/_next/static/chunks/app/setup/page-182018a3c6397345.js +0 -1
  99. package/dist/src/web/nextui/_next/static/chunks/framework-43665103d101a22d.js +0 -25
  100. package/dist/src/web/nextui/_next/static/chunks/main-50cc0a98559591ce.js +0 -1
  101. package/dist/src/web/nextui/_next/static/chunks/main-app-c9dc13756d166550.js +0 -1
  102. package/dist/src/web/nextui/_next/static/chunks/pages/_app-6b79a29ad0d63b21.js +0 -1
  103. package/dist/src/web/nextui/_next/static/chunks/pages/_error-9aeb3e4d490fe4b8.js +0 -1
  104. package/dist/src/web/nextui/_next/static/chunks/webpack-6e474e42be502dd7.js +0 -1
  105. package/dist/src/web/nextui/_next/static/css/a35c840ac696f161.css +0 -1
  106. package/dist/src/web/nextui/api +0 -1
  107. package/src/__mocks__/esm.ts +0 -3
  108. package/src/assertions.ts +0 -580
  109. package/src/cache.ts +0 -109
  110. package/src/esm.ts +0 -13
  111. package/src/evaluator.ts +0 -500
  112. package/src/index.ts +0 -52
  113. package/src/logger.ts +0 -46
  114. package/src/main.ts +0 -442
  115. package/src/matchers.ts +0 -120
  116. package/src/onboarding.ts +0 -69
  117. package/src/prompts.ts +0 -39
  118. package/src/providers/anthropic.ts +0 -88
  119. package/src/providers/azureopenai.ts +0 -299
  120. package/src/providers/llama.ts +0 -95
  121. package/src/providers/localai.ts +0 -111
  122. package/src/providers/ollama.ts +0 -89
  123. package/src/providers/openai.ts +0 -337
  124. package/src/providers/replicate.ts +0 -99
  125. package/src/providers/scriptCompletion.ts +0 -35
  126. package/src/providers/shared.ts +0 -34
  127. package/src/providers.ts +0 -192
  128. package/src/share.ts +0 -27
  129. package/src/suggestions.ts +0 -63
  130. package/src/table.ts +0 -43
  131. package/src/tableOutput.html +0 -52
  132. package/src/telemetry.ts +0 -70
  133. package/src/types.ts +0 -299
  134. package/src/updates.ts +0 -46
  135. package/src/util.ts +0 -543
  136. package/src/web/nextui/.eslintrc.json +0 -3
  137. package/src/web/nextui/next.config.js +0 -14
  138. package/src/web/nextui/package-lock.json +0 -4644
  139. package/src/web/nextui/package.json +0 -47
  140. package/src/web/nextui/public/favicon.ico +0 -0
  141. package/src/web/nextui/public/logo.svg +0 -30
  142. package/src/web/nextui/src/app/Home.css +0 -3
  143. package/src/web/nextui/src/app/api/route.ts +0 -6
  144. package/src/web/nextui/src/app/components/DarkMode.css +0 -22
  145. package/src/web/nextui/src/app/components/DarkMode.tsx +0 -17
  146. package/src/web/nextui/src/app/components/Logo.css +0 -32
  147. package/src/web/nextui/src/app/components/Logo.tsx +0 -11
  148. package/src/web/nextui/src/app/components/PageShell.css +0 -33
  149. package/src/web/nextui/src/app/components/PageShell.tsx +0 -87
  150. package/src/web/nextui/src/app/eval/ConfigModal.tsx +0 -84
  151. package/src/web/nextui/src/app/eval/Eval.css +0 -13
  152. package/src/web/nextui/src/app/eval/Eval.tsx +0 -79
  153. package/src/web/nextui/src/app/eval/EvalOutputPromptDialog.tsx +0 -127
  154. package/src/web/nextui/src/app/eval/ResultsCharts.tsx +0 -355
  155. package/src/web/nextui/src/app/eval/ResultsTable.css +0 -179
  156. package/src/web/nextui/src/app/eval/ResultsTable.tsx +0 -503
  157. package/src/web/nextui/src/app/eval/ResultsView.tsx +0 -301
  158. package/src/web/nextui/src/app/eval/ShareModal.tsx +0 -70
  159. package/src/web/nextui/src/app/eval/[id]/not-found.tsx +0 -5
  160. package/src/web/nextui/src/app/eval/[id]/page.css +0 -9
  161. package/src/web/nextui/src/app/eval/[id]/page.tsx +0 -20
  162. package/src/web/nextui/src/app/eval/index.css +0 -0
  163. package/src/web/nextui/src/app/eval/page.tsx +0 -8
  164. package/src/web/nextui/src/app/eval/store.ts +0 -18
  165. package/src/web/nextui/src/app/eval/types.ts +0 -20
  166. package/src/web/nextui/src/app/globals.css +0 -58
  167. package/src/web/nextui/src/app/layout.tsx +0 -25
  168. package/src/web/nextui/src/app/page.tsx +0 -7
  169. package/src/web/nextui/src/app/setup/AssertsForm.tsx +0 -118
  170. package/src/web/nextui/src/app/setup/PromptDialog.tsx +0 -77
  171. package/src/web/nextui/src/app/setup/PromptsSection.tsx +0 -190
  172. package/src/web/nextui/src/app/setup/ProviderConfigDialog.tsx +0 -99
  173. package/src/web/nextui/src/app/setup/ProviderSelector.tsx +0 -149
  174. package/src/web/nextui/src/app/setup/RunTestSuiteButton.tsx +0 -88
  175. package/src/web/nextui/src/app/setup/TestCaseDialog.tsx +0 -108
  176. package/src/web/nextui/src/app/setup/TestCasesSection.tsx +0 -154
  177. package/src/web/nextui/src/app/setup/VarsForm.tsx +0 -57
  178. package/src/web/nextui/src/app/setup/page.css +0 -3
  179. package/src/web/nextui/src/app/setup/page.tsx +0 -160
  180. package/src/web/nextui/src/util/api.ts +0 -1
  181. package/src/web/nextui/src/util/store.ts +0 -53
  182. package/src/web/nextui/tsconfig.json +0 -28
  183. package/src/web/server.ts +0 -151
  184. /package/dist/src/web/nextui/_next/static/{US6gOx8LHTX_Hzm9aYNrC → Bl3o5lF4ON7Fjki46lPhr}/_ssgManifest.js +0 -0
@@ -1,355 +0,0 @@
1
- import React, { useRef, useEffect, useState } from 'react';
2
- import {
3
- Chart,
4
- BarController,
5
- LineController,
6
- ScatterController,
7
- CategoryScale,
8
- LinearScale,
9
- BarElement,
10
- LineElement,
11
- PointElement,
12
- Tooltip,
13
- Colors,
14
- } from 'chart.js';
15
- import Select from '@mui/material/Select';
16
- import MenuItem from '@mui/material/MenuItem';
17
- import FormControl from '@mui/material/FormControl';
18
- import Dialog from '@mui/material/Dialog';
19
- import DialogTitle from '@mui/material/DialogTitle';
20
- import DialogContent from '@mui/material/DialogContent';
21
- import { useTheme } from '@mui/material/styles';
22
- import Paper from '@mui/material/Paper';
23
- import IconButton from '@mui/material/IconButton';
24
- import CloseIcon from '@mui/icons-material/Close';
25
- import { ErrorBoundary } from 'react-error-boundary';
26
-
27
- import { useStore } from './store';
28
-
29
- import type { VisibilityState } from '@tanstack/table-core';
30
- import type { EvalTable } from './types';
31
-
32
- interface ResultsChartsProps {
33
- columnVisibility: VisibilityState;
34
- }
35
-
36
- interface ChartProps {
37
- table: EvalTable;
38
- }
39
-
40
- const COLOR_PALETTE = [
41
- '#fd7f6f',
42
- '#7eb0d5',
43
- '#b2e061',
44
- '#bd7ebe',
45
- '#ffb55a',
46
- '#ffee65',
47
- '#beb9db',
48
- '#fdcce5',
49
- '#8bd3c7',
50
- ];
51
-
52
- Chart.register(
53
- BarController,
54
- LineController,
55
- ScatterController,
56
- CategoryScale,
57
- LinearScale,
58
- BarElement,
59
- LineElement,
60
- PointElement,
61
- Tooltip,
62
- Colors,
63
- );
64
-
65
- function HistogramChart({ table }: ChartProps) {
66
- const histogramCanvasRef = useRef(null);
67
- const histogramChartInstance = useRef<Chart | null>(null);
68
-
69
- useEffect(() => {
70
- if (!histogramCanvasRef.current) {
71
- return;
72
- }
73
-
74
- if (histogramChartInstance.current) {
75
- histogramChartInstance.current.destroy();
76
- }
77
-
78
- // Calculate bins and their counts
79
- const scores = table.body.flatMap((row) => row.outputs.map((output) => output.score));
80
- const maxScore = Math.max(...scores);
81
- const minScore = Math.min(...scores);
82
- const range = Math.ceil(maxScore) - Math.floor(minScore); // Adjust the range to be between whole numbers
83
- const binSize = range / 10; // Define the size of each bin
84
- const bins = Array.from({ length: 11 }, (_, i) =>
85
- parseFloat((Math.floor(minScore) + i * binSize).toFixed(2)),
86
- );
87
-
88
- const datasets = table.head.prompts.map((prompt, promptIdx) => {
89
- const scores = table.body.flatMap((row) => row.outputs[promptIdx].score);
90
- const counts = bins.map(
91
- (bin) => scores.filter((score) => score >= bin && score < bin + binSize).length,
92
- );
93
- return {
94
- label: `Prompt ${promptIdx + 1}`,
95
- data: counts,
96
- backgroundColor: COLOR_PALETTE[promptIdx % COLOR_PALETTE.length],
97
- };
98
- });
99
-
100
- histogramChartInstance.current = new Chart(histogramCanvasRef.current, {
101
- type: 'bar',
102
- data: {
103
- labels: bins,
104
- datasets,
105
- },
106
- options: {
107
- animation: false,
108
- plugins: {
109
- title: {
110
- display: true,
111
- text: 'Score Distribution',
112
- },
113
- legend: {
114
- display: false,
115
- },
116
- tooltip: {
117
- callbacks: {
118
- title: function (context) {
119
- const datasetIndex = context[0].datasetIndex;
120
- return `Prompt ${datasetIndex + 1}`;
121
- },
122
- label: function (context) {
123
- const labelIndex = context.dataIndex;
124
- const lowerBound = bins[labelIndex];
125
- const upperBound = bins[labelIndex + 1];
126
- return `${lowerBound} <= score < ${upperBound}`;
127
- },
128
- },
129
- },
130
- },
131
- },
132
- });
133
- }, [table]);
134
-
135
- return <canvas ref={histogramCanvasRef} style={{ maxHeight: '300px' }}></canvas>;
136
- }
137
-
138
- function PassRateChart({ table }: ChartProps) {
139
- const passRateCanvasRef = useRef(null);
140
- const passRateChartInstance = useRef<Chart | null>(null);
141
-
142
- useEffect(() => {
143
- if (!passRateCanvasRef.current) {
144
- return;
145
- }
146
-
147
- if (passRateChartInstance.current) {
148
- passRateChartInstance.current.destroy();
149
- }
150
-
151
- const datasets = table.head.prompts.map((prompt, promptIdx) => {
152
- const outputs = table.body.flatMap((row) => row.outputs[promptIdx]);
153
- const passCount = outputs.filter((output) => output.pass).length;
154
- const passRate = (passCount / outputs.length) * 100;
155
- return {
156
- label: `Prompt ${promptIdx + 1}`,
157
- data: [passRate],
158
- backgroundColor: COLOR_PALETTE[promptIdx % COLOR_PALETTE.length],
159
- };
160
- });
161
-
162
- passRateChartInstance.current = new Chart(passRateCanvasRef.current, {
163
- type: 'bar',
164
- data: {
165
- labels: ['Pass Rate (%)'],
166
- datasets,
167
- },
168
- options: {
169
- animation: false,
170
- plugins: {
171
- title: {
172
- display: true,
173
- text: 'Pass rate',
174
- },
175
- legend: {
176
- display: true,
177
- },
178
- },
179
- },
180
- });
181
- }, [table]);
182
-
183
- return <canvas ref={passRateCanvasRef} style={{ maxHeight: '300px' }}></canvas>;
184
- }
185
-
186
- function ScatterChart({ table }: ChartProps) {
187
- const scatterCanvasRef = useRef(null);
188
- const scatterChartInstance = useRef<Chart | null>(null);
189
- const [xAxisPrompt, setXAxisPrompt] = useState(0);
190
- const [yAxisPrompt, setYAxisPrompt] = useState(1);
191
- const [open, setOpen] = useState(false);
192
-
193
- useEffect(() => {
194
- if (!scatterCanvasRef.current) {
195
- return;
196
- }
197
-
198
- if (scatterChartInstance.current) {
199
- scatterChartInstance.current.destroy();
200
- }
201
-
202
- const scores = table.body.flatMap((row) => row.outputs.map((output) => output.score));
203
- const minScore = Math.min(...scores);
204
- const maxScore = Math.max(...scores);
205
-
206
- const data = table.body.map((row) => {
207
- const prompt1Score = row.outputs[xAxisPrompt].score;
208
- const prompt2Score = row.outputs[yAxisPrompt].score;
209
- let backgroundColor;
210
- if (prompt2Score > prompt1Score) {
211
- backgroundColor = 'green';
212
- } else if (prompt2Score < prompt1Score) {
213
- backgroundColor = 'red';
214
- } else {
215
- backgroundColor = 'gray';
216
- }
217
- return {
218
- x: prompt1Score,
219
- y: prompt2Score,
220
- backgroundColor,
221
- };
222
- });
223
-
224
- scatterChartInstance.current = new Chart(scatterCanvasRef.current, {
225
- type: 'scatter',
226
- data: {
227
- datasets: [
228
- {
229
- data,
230
- backgroundColor: data.map((point) => point.backgroundColor),
231
- },
232
- {
233
- type: 'line',
234
- data: [
235
- // @ts-ignore: types seem wrong, it wants backgroundColor
236
- { x: minScore, y: minScore },
237
- // @ts-ignore: types seem wrong, it wants backgroundColor
238
- { x: maxScore, y: maxScore },
239
- ],
240
- borderColor: 'gray',
241
- borderWidth: 1,
242
- borderDash: [5, 5],
243
- pointRadius: 0,
244
- },
245
- ],
246
- },
247
- options: {
248
- animation: false,
249
- plugins: {
250
- legend: {
251
- display: false,
252
- },
253
- tooltip: {
254
- callbacks: {
255
- label: function (tooltipItem) {
256
- const row = table.body[tooltipItem.dataIndex];
257
- let prompt1Text = row.outputs[0].text;
258
- let prompt2Text = row.outputs[1].text;
259
- if (prompt1Text.length > 30) {
260
- prompt1Text = prompt1Text.substring(0, 30) + '...';
261
- }
262
- if (prompt2Text.length > 30) {
263
- prompt2Text = prompt2Text.substring(0, 30) + '...';
264
- }
265
- return `Output 1: ${prompt1Text}\nOutput 2: ${prompt2Text}`;
266
- },
267
- },
268
- },
269
- },
270
- scales: {
271
- x: {
272
- title: {
273
- display: true,
274
- text: `Prompt ${xAxisPrompt + 1} Score`,
275
- },
276
- },
277
- y: {
278
- title: {
279
- display: true,
280
- text: `Prompt ${yAxisPrompt + 1} Score`,
281
- },
282
- },
283
- },
284
- },
285
- });
286
- }, [table, xAxisPrompt, yAxisPrompt]);
287
-
288
- return (
289
- <>
290
- <Dialog open={open} onClose={() => setOpen(false)}>
291
- <DialogTitle>Compare prompt outputs</DialogTitle>
292
- <DialogContent>
293
- <FormControl sx={{ m: 1, minWidth: 120 }}>
294
- <Select value={xAxisPrompt} onChange={(e) => setXAxisPrompt(Number(e.target.value))}>
295
- {table.head.prompts.map((prompt, idx) => (
296
- <MenuItem key={idx} value={idx}>
297
- Prompt {idx + 1}
298
- </MenuItem>
299
- ))}
300
- </Select>
301
- </FormControl>
302
- <FormControl sx={{ m: 1, minWidth: 120 }}>
303
- <Select value={yAxisPrompt} onChange={(e) => setYAxisPrompt(Number(e.target.value))}>
304
- {table.head.prompts.map((prompt, idx) => (
305
- <MenuItem key={idx} value={idx}>
306
- Prompt {idx + 1}
307
- </MenuItem>
308
- ))}
309
- </Select>
310
- </FormControl>
311
- </DialogContent>
312
- </Dialog>
313
- <canvas
314
- ref={scatterCanvasRef}
315
- style={{ maxHeight: '300px', cursor: 'pointer' }}
316
- onClick={() => setOpen(true)}
317
- ></canvas>
318
- </>
319
- );
320
- }
321
-
322
- export default function ResultsCharts({ columnVisibility }: ResultsChartsProps) {
323
- const theme = useTheme();
324
- Chart.defaults.color = theme.palette.mode === 'dark' ? '#aaa' : '#666';
325
- const [showCharts, setShowCharts] = useState(true);
326
-
327
- const { table } = useStore();
328
- if (!table || !showCharts) {
329
- return null;
330
- }
331
-
332
- return (
333
- <ErrorBoundary fallback={null}>
334
- <Paper style={{ position: 'relative', padding: theme.spacing(3) }}>
335
- <IconButton
336
- style={{ position: 'absolute', right: 0, top: 0 }}
337
- onClick={() => setShowCharts(false)}
338
- >
339
- <CloseIcon />
340
- </IconButton>
341
- <div style={{ display: 'flex', justifyContent: 'space-between', width: '100%' }}>
342
- <div style={{ width: '33%' }}>
343
- <PassRateChart table={table} />
344
- </div>
345
- <div style={{ width: '33%' }}>
346
- <HistogramChart table={table} />
347
- </div>
348
- <div style={{ width: '33%' }}>
349
- <ScatterChart table={table} />
350
- </div>
351
- </div>
352
- </Paper>
353
- </ErrorBoundary>
354
- );
355
- }
@@ -1,179 +0,0 @@
1
- table,
2
- .divTable {
3
- border: 1px solid var(--table-border-color);
4
- border-collapse: collapse;
5
- width: 100%;
6
-
7
- margin: 1rem 0;
8
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
9
- }
10
-
11
- ins {
12
- background-color: var(--insert-highlight-color);
13
- text-decoration: none;
14
- }
15
-
16
- del {
17
- background-color: var(--delete-highlight-color);
18
- text-decoration: strikethrough;
19
- }
20
-
21
- .tr {
22
- display: flex;
23
- }
24
-
25
- tr,
26
- .tr {
27
- width: fit-content;
28
- }
29
-
30
- tr:hover,
31
- .tr:hover {
32
- background-color: rgba(0, 0, 0, 0.05);
33
- }
34
-
35
- th,
36
- .th,
37
- td,
38
- .td {
39
- position: relative;
40
- box-shadow: inset 0 0 0 1px var(--border-color);
41
- vertical-align: top;
42
-
43
- padding: 1.5rem;
44
- }
45
-
46
- th.variable,
47
- .th.variable,
48
- td.variable,
49
- .td.variable {
50
- background-color: var(--variable-background-color);
51
- }
52
-
53
- tr.header {
54
- background-color: var(--header-background-color);
55
- }
56
-
57
- th,
58
- .th {
59
- padding: 1rem;
60
- position: relative;
61
- text-align: center;
62
- vertical-align: bottom;
63
- }
64
-
65
- th .action {
66
- cursor: pointer;
67
- margin-left: 0.5rem;
68
- }
69
-
70
- tr .cell {
71
- }
72
-
73
- tr .cell-actions {
74
- display: flex;
75
- gap: 0.5rem;
76
- visibility: hidden;
77
- position: absolute;
78
- bottom: 1.25rem;
79
- right: 0;
80
- line-height: 0;
81
- font-size: 1.75rem;
82
- }
83
-
84
- tr .cell-detail {
85
- visibility: hidden;
86
- position: absolute;
87
- bottom: 0.25rem;
88
- margin-top: 1rem;
89
- font-size: 0.75rem;
90
- color: #888;
91
- }
92
-
93
- tr:hover .cell-actions,
94
- tr:hover .cell-detail {
95
- visibility: visible;
96
- }
97
-
98
- tr .cell-actions .action {
99
- cursor: pointer;
100
- }
101
-
102
- th .smalltext {
103
- visibility: hidden;
104
- font-weight: normal;
105
- font-size: 0.75rem;
106
- color: var(--smalltext-color);
107
- }
108
-
109
- th:hover .smalltext {
110
- visibility: visible;
111
- }
112
-
113
- th .summary {
114
- font-weight: normal;
115
- font-size: 0.8rem;
116
- padding: 0.25rem;
117
- }
118
-
119
- th .summary.highlight {
120
- background-color: var(--success-background-color);
121
- }
122
-
123
- td,
124
- .td {
125
- }
126
-
127
- td .status {
128
- margin-bottom: 0.5rem;
129
- font-weight: bold;
130
- }
131
-
132
- td .score {
133
- font-weight: normal;
134
- }
135
-
136
- td .pass {
137
- color: var(--pass-color);
138
- }
139
-
140
- td .fail {
141
- color: var(--fail-color);
142
- }
143
-
144
- .first-prompt-col {
145
- border-left: 2px solid #888;
146
- }
147
-
148
- .first-prompt-row {
149
- border-top: 2px solid #888;
150
- }
151
-
152
- .resizer {
153
- position: absolute;
154
- right: 0;
155
- top: 0;
156
- height: 100%;
157
- width: 5px;
158
- cursor: col-resize;
159
- user-select: none;
160
- touch-action: none;
161
-
162
- background: var(--text-color);
163
- opacity: 0.5;
164
- }
165
-
166
- .resizer.isResizing {
167
- background: var(--text-color);
168
- opacity: 1;
169
- }
170
-
171
- @media (hover: hover) {
172
- .resizer {
173
- opacity: 0;
174
- }
175
-
176
- *:hover > .resizer {
177
- opacity: 1;
178
- }
179
- }