@recogito/recogito-connections
Version:
A plugin for drawing connections between annotations
93 lines (69 loc) • 2.58 kB
JSX
import EventEmitter from 'tiny-emitter';
import WebAnnotation from '@recogito/recogito-client-core/src/WebAnnotation';
import NetworkCanvas from './NetworkCanvas';
import mountEditor from './editor/mountEditor';
/** Checks if the given annotation represents a connection **/
const isConnection = annotation => {
const targets = Array.isArray(annotation.target) ?
annotation.target : [ annotation.target ];
if (targets.length !== 2)
return false;
return targets.every(t => t.id);
}
class ConnectionsPlugin extends EventEmitter {
constructor(arg, conf) {
super();
const instances = arg || [];
// Configuration options
const config = conf || {};
// RecogitoJS/Annotorious instances
this.instances = Array.isArray(instances) ?
instances : [ instances ];
// Single network canvas, covering the browser viewport
this.canvas = new NetworkCanvas(this.instances, config);
this.instances.forEach(this.patchInstance);
if (!config.disableEditor)
mountEditor(this.canvas, this, config);
}
/**
* Applies plugin intercepts to a RecogitoJS/Annotorious instance.
*/
patchInstance = instance => {
// Intercept + monkeypatch API methods
const _setAnnotations = instance.setAnnotations;
instance.setAnnotations = arg => {
const all = (arg || []);
// Split text annotations from connections
const annotations = all.filter(a => !isConnection(a));
const connections = all.filter(a => isConnection(a));
// Set annotations on instance first
return _setAnnotations(annotations).then(() => {
// Then create relations
const wrapped = connections.map(a => new WebAnnotation(a));
this.canvas.setAnnotations(wrapped);
});
}
// When annotations are deleted, also delete
// in-/outgoing connections
instance.on('deleteAnnotation', annotation => {
const deleted = this.canvas.deleteConnectionsForId(annotation.id);
deleted.forEach(annotation => {
this.emit('deleteConnection', annotation.underlying);
});
});
}
destroy = () => {
this.canvas.destroy();
}
register = instance => {
this.patchInstance(instance);
this.canvas.registerInstance(instance);
this.instances.push(instance);
}
unregister = instance => {
// TODO need to remove patching!
this.instances = this.instances.filter(i => i !== instance);
this.canvas.unregisterInstance(instance);
}
}
export default (instances, config) => new ConnectionsPlugin(instances, config);