Movika Graph Editor was created for visual representation and easy manifest data editing. It helps user to connect manifest chapters, add new chapters and chapter controls with a friendly UI.
Native mobile build README
import { GraphEditor } from "movika-graph-editor";
// create editor container
const editorContainer = document.createElement("div");
// add it to DOM
document.body.appendChild(editorContainer);
// init GraphEditor
const editor = new GraphEditor(editorContainer);
// set manifest data
editor.update(ManifestData);
Graph editor also can be safely destroyed if necessary. I.e. when editor is used in React project.
React.useEffect(() => {
// React component unmount
return () => {
// safely destroy editor object
editor.dispose();
}
}, [])
Graph editor can be initialized with options if necessary
const editor = new GraphEditor(editorContainer, options);
These are the available config options for editor. All of them are optional.
{
// Possible values:
// - "edit" - full editor mode which will enable all instruments
// - "read" - read only mode
mode: "edit", // default
// Specify editor interface localization.
// Possible values:
// - "en"
// - "ru"
lang: "en"; //default
// Specify custom translation keys that will override default translation.
translation: Partial<Translation>;
}
GraphEditor has a public API
- Change editor zoom value
NOTE: If the value is not in [min, max] range zoomConfig value then closest value will be applied.
I.e. "value" is smaller that "min" thenzoomConfig().min
will be applied.
editor.zoom(value: number);
- Zoom map to selected coordinates
editor.zoomTo(coordinates: [x, y], scale?: number);
- Get editor zoom config information
editor.zoomConfig();
// returns
{
min: number;
max: number;
step: number;
}
- Enable/disable zoom
editor.zoomEnable();
editor.zoomDisable();
- Mark chapter with id as selected.
editor.selectChapter(chapterId: string);
// It is also possible to focus selected chapter if second parameter is passed
editor.selectChapter(chapterId: string, true);
// to select multiple chapter pass array of ids
editor.selectChapter(chapterId: string[]);
- Hover over chapters with ids.
editor.hoverOverChapters(chapterId: string);
// to select multiple chapter pass array of ids
editor.hoverOverChapters(chapterIds: string[]);
- Focus on chapter with id.
editor.focusChapter(chapterId: string);
- Zoom to fit graph in editor window
editor.recenterGraph();
- Freeze graph (freeze/unfreeze keyboard events, will freeze interaction with graph in future)
editor.setGraphFrozen(true);
editor.setGraphFrozen(false);
- Enable/disable
add chapter
instrument
// enable instrument
editor.toggleAddChapterTool();
// disable instrument
editor.toggleAddChapterTool(false);
- Show/hide chapter errors while editing
// show chapter errors
editor.setChaptersValidationErrors({
"a4c3c0a1-00fd-4494-a4b1-2ce3e33ae57b": [
{ message: "В проекте есть ноды без видео", title: "Ошибка 1005" },
{ message: "В проекте отсутствуют необходимые связи между нодами", title: "Ошибка 1007" },
],
});
// hide chapter errors
editor.setChaptersValidationErrors({});
- Enable/disable hand tool to zoom with mouse down. By default it is always disabled.
// show/hide grid
editor.toggleHandTool(enabled => {
// process "enabled" flag here
});
- Set visible chapter ids (read-mode only)
// set
editor.setVisitedChapters(chapterIds: string[]);
// reset
editor.setVisitedChapters([]);
- Set chapter cover urls
type VideoInfo = {
id: string;
cover: string;
title?: string; // edit-mode only
}
// set
editor.updateVideosInfo(videosInfo: (VideoInfo[]);
// reset
editor.updateVideosInfo([]);
Editor has list of events to subscribe and get updated information such as control
(editor buttons click), zoom
, zoomEnd
, selectChapters
, deleteChapters
, selectBranches
, manifestUpdate
and events
.
It is triggered whenever editor control is clicked
editor.on("control", event => {
// possible "event" data
{ name: "openEditor"; chapterId: string } // "Open editor" button clicked
{ name: "openPreview"; chapterId: string } // "Preview from this node" or "Watch again" (view mode) buttons clicked
{ name: "changeVideo"; chapterIds: string[] } // "Change video" or "Choose video" button clicked
{ name: "renameControl"; chapterId: string; control: Control; containerId: string } // Control "Rename" button clicked
{ name: "deleteControl"; chapterId: string; controlId: string; containerId: string } // Control "Delete" button clicked
{ name: "addChapterStopped" } // Add chapter instrument stopped
{ name: "addControl"; type: ControlType; nodeId: string } // "Add control" button clicked
});
Although it is possible to delete Chapter
or Control
from editor usually additional confirmation is required. This is why those events are delegated to external usage.
It is triggered on any zoom change
editor.on("zoom", zoom => {
// zoom object
{
x: number;
y: number;
value: number;
}
});
It is triggered when branch(es) is/are selected via editor
editor.on("selectBranches", branchIds => {
// branchIds - string array of branch ids
});
It is triggered whenever manifest object is updated via editor
editor.on("manifestUpdate", updatedManifest => {
// updatedManifest - Manifest object
});
It is triggered whenever some action happened via editor. On this actions graph doesn't update manifest internally.
editor.on("actions", action => {
// possible "action" data
{ name: "deleteChapters"; context: Pick<Chapter, "id">[] } // deleting nodes with ids requested
{ name: "updateChapterOrder"; context: Pick<Chapter, "id" | "order"> } // updating node's order requested
{ // Chapter/Chapters "Rename" button clicked
name: "renameChapters";
context: { triggerNodeId: string; selectedNodesIds: string[]};
}
});
It is triggered whenever some events happened via editor. On this events graph update manifest internally, but not export updated manifest.
editor.on("events", event => {
// possible "event" data
{ name: "chaptersAdded"; context: { chapter: Chapter; graphChapter: GraphEditChapter}[] } // Chapter was added to manifest
{
name: "coordinatesUpdated";
context: {
id: string;
x: number;
y: number
}[]
} // Coordinates of chapters were changed
{ name: "chaptersSelected"; context: Pick <Chapter, "id"> []} // list of chapters that were selected
{ name: "chapterUpdated"; context: Chapter } // chapter that was updated
{ name: "zoom"; context: ZoomState } // on zoom event (fires multiple times during animation)
});
It is triggered whenever a notification has to be presented
editor.on("notification", notification => {
/**
* Notification object
* {
* id: "remove_init_chapter" | "copy_chapter" | "copy_multiple_chapters";
* defaultTranslation: string;
* }
*/
});