gazeplotter
Version:
Gazeplotter is a Svelte application for visualizing eye-tracking data.
121 lines (120 loc) • 5.14 kB
JavaScript
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);
}
}