UNPKG

gazeplotter

Version:

Gazeplotter is a Svelte application for visualizing eye-tracking data.

121 lines (120 loc) 5.14 kB
import { EyeClassifier } from '../EyeClassifier/EyeClassifier.ts'; import { EyeWriter } from '../EyeWriter/EyeWriter.ts'; import { EyeParser } from '../EyeParser/EyeParser.ts'; import { AbstractEyeDeserializer } from '../EyeDeserializer/AbstractEyeDeserializer.ts'; import { BeGazeEyeDeserializer } from '../EyeDeserializer/BeGazeEyeDeserializer.ts'; import { GazePointEyeDeserializer } from '../EyeDeserializer/GazePointEyeDeserializer.ts'; import { OgamaEyeDeserializer } from '../EyeDeserializer/OgamaEyeDeserializer.ts'; import { VarjoEyeDeserializer } from '../EyeDeserializer/VarjoEyeDeserializer.ts'; import { CsvEyeDeserializer } from '../EyeDeserializer/CsvEyeDeserializer.ts'; import { TobiiEyeDeserializer } from '../EyeDeserializer/TobiiEyeDeserializer.ts'; import { EyeSplitter } from '../EyeSplitter/EyeSplitter.ts'; import { EyeRefiner } from '../EyeRefiner/EyeRefiner.ts'; import { CsvSegmentedEyeDeserializer } from '../EyeDeserializer/CsvSegmentedEyeDeserializer.ts'; export class EyePipeline { fileNames; fileCount = -1; classifier = new EyeClassifier(); writer = new EyeWriter(); deserializer = null; requestUserInputCallback; rowIndex = 0; get isAllProcessed() { return this.fileCount === this.fileNames.length - 1; } get currentFileName() { const name = this.fileNames[this.fileCount + 1]; if (name === undefined) throw new Error('File name is undefined'); return name; } constructor(fileNames, requestUserInputCallback) { this.fileNames = fileNames; this.requestUserInputCallback = requestUserInputCallback; } async addNewStream(stream) { const parser = new EyeParser(stream); const firstTextChunk = await parser.getTextChunk(); const settings = await this.classify(firstTextChunk); const splitter = new EyeSplitter(settings); const userStringInput = settings.type === 'tobii-with-event' ? await this.requestUserInputCallback() : ''; this.processChunk(firstTextChunk, settings, splitter, userStringInput); while (!parser.isDone) { const chunk = await parser.getTextChunk(); this.processChunk(chunk, settings, splitter, userStringInput); } this.releaseAfterFile(splitter, settings, userStringInput); if (this.isAllProcessed) { const refiner = new EyeRefiner(); return refiner.process(this.writer.data); } return null; } releaseAfterFile(splitter, settings, userStringInput) { const dataFromSplitter = splitter.release(); for (let i = 0; i < dataFromSplitter.length; i++) { this.processRow(dataFromSplitter[i].split(settings.columnDelimiter), settings, userStringInput); } this.fileCount++; this.rowIndex = 0; this.deserializer = null; } classify(chunk) { const classifier = this.classifier; return classifier.classify(chunk); } processChunk(chunk, settings, splitter, userStringInput) { const rows = splitter.splitChunk(chunk); for (let i = 0; i < rows.length; i++) { this.processRow(rows[i].split(settings.columnDelimiter), settings, userStringInput); } } processRow(row, settings, userStringInput) { const headerRowId = settings.headerRowId; if (this.rowIndex < headerRowId) { this.rowIndex++; return; } if (this.rowIndex === headerRowId) { this.deserializer = this.getDeserializer(row, this.currentFileName, settings, userStringInput); this.rowIndex++; return; } if (this.deserializer == null) throw new Error('Deserializer is undefined'); this.rowIndex++; const parsedRow = this.deserializer.deserialize(row); if (parsedRow === null) return; if (Array.isArray(parsedRow)) return parsedRow.forEach(row => this.writer.add(row)); this.writer.add(parsedRow); } getDeserializer(row, fileName, settings, userStringInput) { switch (settings.type) { case 'begaze': return new BeGazeEyeDeserializer(row); case 'tobii': return this.getTobiiReducer(row, userStringInput); case 'tobii-with-event': return this.getTobiiReducer(row, userStringInput); case 'gazepoint': return new GazePointEyeDeserializer(row, fileName); case 'ogama': return new OgamaEyeDeserializer(row, fileName); case 'varjo': return new VarjoEyeDeserializer(row, fileName); case 'csv': return new CsvEyeDeserializer(row); case 'csv-segmented': return new CsvSegmentedEyeDeserializer(row); default: throw new Error('File type row reducer not implemented'); } } getTobiiReducer(row, userInput) { return new TobiiEyeDeserializer(row, userInput); } }