(rows: Record<string, unknown>[], spec: ChartSpec)
| 214 | } |
| 215 | |
| 216 | function buildLineData(rows: Record<string, unknown>[], spec: ChartSpec): LineChartRenderData { |
| 217 | const xField = spec.encoding.x! |
| 218 | const yField = spec.encoding.y! |
| 219 | const seriesField = spec.encoding.series |
| 220 | |
| 221 | if (!seriesField) return aggregateByLabel(rows, xField, yField) |
| 222 | |
| 223 | assertFieldExists(rows, seriesField) |
| 224 | const labels: string[] = [] |
| 225 | const labelIndex = new Map<string, number>() |
| 226 | const seriesNames: string[] = [] |
| 227 | const seriesIndex = new Map<string, number>() |
| 228 | const matrix: number[][] = [] |
| 229 | |
| 230 | for (const row of rows) { |
| 231 | const label = toLabel(row[xField]) |
| 232 | const seriesName = toLabel(row[seriesField]) |
| 233 | let xIndex = labelIndex.get(label) |
| 234 | if (xIndex === undefined) { |
| 235 | xIndex = labels.length |
| 236 | labelIndex.set(label, xIndex) |
| 237 | labels.push(label) |
| 238 | for (const values of matrix) values.push(0) |
| 239 | } |
| 240 | |
| 241 | let sIndex = seriesIndex.get(seriesName) |
| 242 | if (sIndex === undefined) { |
| 243 | sIndex = seriesNames.length |
| 244 | seriesIndex.set(seriesName, sIndex) |
| 245 | seriesNames.push(seriesName) |
| 246 | matrix.push(Array(labels.length).fill(0)) |
| 247 | } |
| 248 | |
| 249 | matrix[sIndex][xIndex] += toNumber(row[yField], yField) |
| 250 | } |
| 251 | |
| 252 | const series = seriesNames.map((name, index) => ({ name, values: matrix[index] })) |
| 253 | return { |
| 254 | labels, |
| 255 | values: series[0]?.values ?? [], |
| 256 | series, |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | function buildHeatmapData(rows: Record<string, unknown>[], spec: ChartSpec): HeatmapChartRenderData { |
| 261 | const xField = spec.encoding.x! |
no test coverage detected