skip to content
usubeni fantasy logo Usubeni Fantasy

Легкая интеграция профессиональных ментальных карт в ваши веб-проекты - Mind Elixir

/ 10 min read

This Post is Available In: CN EN ES JA KO RU

В нашу эпоху информационного изобилия мы постоянно имеем дело с огромными объемами сложных данных и идей. Традиционное линейное ведение заметок часто не способно передать динамичную природу и взаимосвязи наших мыслей, в то время как ментальные карты служат интуитивным инструментом для заметок, который помогает нам лучше организовывать идеи, структурировать знания и стимулировать творчество — при этом они более удобны в использовании, чем доски или программы для рисования.

Независимо от того, создаете ли вы платформы управления знаниями, образовательные сайты или инструменты для совместной работы, интеграция функциональности ментальных карт может значительно улучшить пользовательский опыт, делая отображение сложной информации и взаимодействие с ней более интуитивным и эффективным.

Если вы хотите добавить возможности ментальных карт в свои веб-проекты, Mind Elixir позволяет интегрировать профессиональные ментальные карты всего несколькими строками кода. Например, в личном блоге вы можете использовать ментальные карты для визуализации структуры знаний статей или создания интерактивных учебных заметок — функции, которые не только делают контент более привлекательным, но и значительно повышают профессиональную привлекательность вашего блога.

Mind Elixir ядро

Открытое JavaScript ядро ментальных карт Mind Elixir предлагает следующие ключевые возможности:

  • Плавный пользовательский опыт Плавные взаимодействия с естественной обратной связью, включая поддержку мобильных устройств.
  • Легковесность и высокая производительность Небольшой размер с быстрой загрузкой и рендерингом, поддержание высокой частоты кадров даже при сложных диаграммах.
  • Независимость от фреймворков Легкая интеграция с React, Vue, Svelte или vanilla проектами — работает автономно или встраивается.
  • Архитектура плагинов Гибкая система плагинов, поддерживающая официальные расширения и пользовательские плагины для модульной функциональности.
  • Поддержка экспорта PNG / HTML Экспорт ментальных карт как изображений или HTML-страниц для легкого обмена и встраивания.
  • Резюме узлов и соединения Поддержка резюме узлов, соединительных линий, тегов и различных стилей узлов для удовлетворения разных потребностей.
  • Поддержка отмены / повтора Полный стек истории операций — любое изменение можно быстро отменить или повторить с уверенностью.
  • Эффективные горячие клавиши Богатые горячие клавиши для повышения продуктивности опытных пользователей.
  • Настройка CSS переменных Легкое управление стилями узлов и общими темами через CSS переменные для высоко настраиваемых, красивых макетов.

Давайте разберем, как быстро интегрировать Mind Elixir в ваши проекты! 🤗

Супер простая интеграция

Установите зависимость:

Terminal window
npm i mind-elixir -S

Импортируйте Mind Elixir:

import MindElixir from "mind-elixir";
import "mind-elixir/style"; // Версии 5.0+ требуют явного импорта стилей

Альтернативно, вы можете подключить его напрямую через тег script:

<script type="module" src="https://cdn.jsdelivr.net/npm/mind-elixir/dist/MindElixir.js"></script>

Перед инициализацией нам нужно стилизовать ваш целевой элемент монтирования. В частности, вам нужно задать ему явные размеры ширины и высоты, обращая особое внимание на высоту. Любой frontend разработчик, который боролся с CSS, знает, что 100% высота может быть сложной в обращении. Давайте используем div высотой 500px в качестве примера.

<div id="map"></div>
<style>
#map {
height: 500px;
width: 100%;
}
</style>

Далее идет фактическая инициализация. Если вам не нужны другие опции инициализации, просто передайте элемент монтирования!

import MindElixir from "mind-elixir";
import "mind-elixir/style";
let options = {
el: "#map", // или HTMLDivElement
};
let mei = new MindElixir(options);
const data = MindElixir.new("новая тема");
mei.init(data);

Вот и все — вы завершили самую базовую интеграцию!

TIP

Попробуйте на CodePen: https://codepen.io/ssshooter/pen/vEOqWjE

Прослушивание событий

Как только вы интегрировали ментальные карты в свой проект, наиболее распространенным требованием является прослушивание событий. Вам нужно отслеживать различные операции с узлами и реагировать на действия пользователя. Например, когда пользователь создает новый узел, вы захотите сохранить его незамедлительно.

Mind Elixir использует bus для отправки событий — этот термин происходит от концепции “шины событий”, где все события отправляются через эту центральную “шину”. Использование похоже на addEventListener браузера; пока у вас есть доступ к bus, вы можете слушать события где угодно.

По состоянию на последнюю версию Mind Elixir 5.0 доступны следующие события:

type EventMap = {
operation: (info: Operation) => void;
selectNode: (nodeObj: NodeObj, e?: MouseEvent) => void;
selectNewNode: (nodeObj: NodeObj) => void;
selectNodes: (nodeObj: NodeObj[]) => void;
unselectNodes: (nodeObj: NodeObj[]) => void;
expandNode: (nodeObj: NodeObj) => void;
linkDiv: () => void;
scale: (scale: number) => void;
move: (data: { dx: number; dy: number }) => void;
updateArrowDelta: (arrow: Arrow) => void;
showContextMenu: (e: MouseEvent) => void;
};

Большинство событий операций с узлами группируются под событием operation. Хватит слов — добавьте это в свой проект и попробуйте манипулировать некоторыми узлами, чтобы увидеть, как это работает:

mei.bus.addListener("operation", (operation) => {
console.log(operation);
});

Иногда прослушивания событий недостаточно. Если вам нужно убедиться, что данные вставлены в базу данных перед их отображением, вам понадобится перехват операций. Добавьте опцию before в ваши options — это объект, где ключи являются операциями, которые вы хотите перехватить. Если вам нужно перехватить операцию addChild, вы можете написать:

let mei = new MindElixir({
// ...
before: {
async addChild(el, obj) {
try {
await saveToDatabase(obj);
return true;
} catch (error) {
console.error("Ошибка добавления дочернего элемента:", error);
return false;
}
},
},
});

Таким образом, дочерний узел будет добавлен только после успешного выполнения saveToDatabase(); если это не удастся, операция вставки будет отменена.

TIP

Попробуйте на CodePen: https://codepen.io/ssshooter/pen/EajBbrM

Перерисовка ментальной карты

Помимо использования поведения по умолчанию ядра Mind Elixir для обновления ментальных карт, вы также можете перерисовывать ментальные карты, напрямую обновляя данные узлов.

Полная структура данных узла выглядит следующим образом:

export interface NodeObj {
topic: string;
id: Uid;
style?: {
fontSize?: string;
color?: string;
background?: string;
fontWeight?: string;
};
children?: NodeObj[];
tags?: string[];
icons?: string[];
hyperLink?: string;
expanded?: boolean;
direction?: Left | Right;
image?: {
url: string;
width: number;
height: number;
fit?: "fill" | "contain" | "cover";
};
branchColor?: string;
dangerouslySetInnerHTML?: string;
note?: string;
}

Изменяя данные узлов, вы можете вставлять изображения, теги, гиперссылки и другие элементы в узлы. Например, вы можете прочитать текущие данные ментальной карты из nodeData экземпляра Mind Elixir, изменить их, а затем вызвать метод refresh для перерисовки ментальной карты.

const data = mind.nodeData;
console.log(data);
data.topic = data.topic + "новые данные";
mind.refresh();

Но что, если вы хотите обновить всю ментальную карту совершенно новыми данными? Это тоже возможно! Передайте данные, соответствующие формату Mind Elixir, в метод refresh, и вы сможете мгновенно обновить всю карту.

import data from "https://esm.sh/mind-elixir/dist/example.js";
mind.refresh(data);

TIP

Попробуйте на CodePen: https://codepen.io/ssshooter/pen/vEOqpOX

Свобода редизайна

Mind Elixir дает вам свободу полностью переработать дизайн ваших ментальных карт.

Во-первых, вы можете легко настроить общий стиль вашей ментальной карты через theme и cssVar. Ядро поставляется с двумя встроенными темами: MindElixir.DARK_THEME и MindElixir.THEME. Если вам нужна пользовательская тема, вы можете создать объект, следующий формату темы, и передать его в Mind Elixir.

Вот полная тема Mind Elixir и как ее использовать:

const PROFESSIONAL_THEME = {
name: "Professional",
type: "light",
palette: ["#2c2c2c", "#404040", "#555555", "#6a6a6a", "#7f7f7f", "#949494", "#a9a9a9"],
cssVar: {
"--node-gap-x": "32px",
"--node-gap-y": "12px",
"--main-gap-x": "68px",
"--main-gap-y": "48px",
"--root-radius": "8px",
"--main-radius": "6px",
"--root-color": "#ffffff",
"--root-bgcolor": "#1a1a1a",
"--root-border-color": "#333333",
"--main-color": "#2c2c2c",
"--main-bgcolor": "#ffffff",
"--topic-padding": "4px",
"--color": "#4a4a4a",
"--bgcolor": "#fafafa",
"--selected": "#666666",
"--panel-color": "#2c2c2c",
"--panel-bgcolor": "#ffffff",
"--panel-border-color": "#e0e0e0",
},
};
let mind = new MindElixir({
el: "#map",
theme: PROFESSIONAL_THEME,
});

Обратите внимание, что сами data также могут содержать theme, которая переопределит theme в options. Это гарантирует, что каждая ментальная карта может иметь свою собственную независимую тему. Если вам нужна фиксированная тема, не забудьте установить theme в data в undefined во время инициализации.

P.S. Если вы хотите изменить тему после инициализации, вы можете использовать метод changeTheme.

Часто используемый main-gap в cssVar может настроить расстояние между основными узлами:

Mind Elixir main-gap

node-gap может настроить внутреннее расстояние узлов:

Mind Elixir node-gap

TIP

Попробуйте на CodePen: https://codepen.io/ssshooter/pen/azOgVKX

Для других параметров, которые нельзя настроить через CSS переменные, вы можете точно настроить их напрямую через CSS переопределения.

Идя глубже, вы можете настроить стили соединительных линий через generateMainBranch и generateSubBranch. (См. ссылку CodePen ниже для примеров)

После написания подходящих функций generateMainBranch и generateSubBranch, если вы обнаружите, что позиции кнопок развертывания/свертывания смещены, вы можете точно настроить их с помощью CSS. Стили по умолчанию:

// Стили кнопок развертывания/свертывания для основных узлов (прямые дочерние элементы корня)
me-main > me-wrapper > me-parent > me-epd {
top: 50%;
transform: translateY(-50%);
}
// Стили кнопок развертывания/свертывания для других дочерних узлов
me-epd {
top: 100%;
transform: translateY(-50%);
}
// Специфические настройки для левосторонних кнопок развертывания/свертывания
.lhs {
& > me-wrapper > me-parent > me-epd {
left: -10px;
}
me-epd {
left: 5px;
}
}
// Специфические настройки для правосторонних кнопок развертывания/свертывания
.rhs {
& > me-wrapper > me-parent > me-epd {
right: -10px;
}
me-epd {
right: 5px;
}
}

TIP

Попробуйте на CodePen: https://codepen.io/ssshooter/pen/WNmZMmq

Стилизация узлов

Если у вас есть потребности в настройке отдельных узлов помимо общего стиля, сами узлы могут иметь настройки style:

//...
{
fontSize?: string
color?: string
background?: string
fontWeight?: string
}
// ...

Если у вас есть очень сильные потребности в настройке узлов и вы чувствуете, что этих конфигураций style совершенно недостаточно, нет проблем — мы вас прикрыли!

Вы можете стать еще более креативными с dangerouslySetInnerHTML, например:

const data = {
nodeData: {
id: "me-root",
topic: "Mind Elixir",
tags: ["Ядро ментальных карт"],
children: [
{
topic: "Настраиваемый Div",
id: "c00a2264f4532615",
children: [
{
topic: "",
id: "c00a2264f4532614",
dangerouslySetInnerHTML:
'<div><style>.title{font-size:50px}</style><div class="title">Заголовок</div><div style="color: red; font-size: 20px;">Привет мир</div></div>',
},
],
},
],
},
};

TIP

Попробуйте на CodePen: https://codepen.io/ssshooter/pen/MYwMrjZ

Экспорт изображений

Благодаря modern-screenshot, который умно преобразует div в изображения с использованием SVG, сохраняя все в целости. В основном, пока вы не делали ничего слишком безумного с dangerouslySetInnerHTML (например, встраивание видео), вы можете экспортировать изображения нормально. @ssshooter/modern-screenshot добавляет дополнительную опцию padding для настройки полей скриншота.

import { domToPng } from "@ssshooter/modern-screenshot";
const download = async () => {
const dataUrl = await domToPng(mind.nodes, {
onCloneNode: (node) => {
const n = node as HTMLDivElement;
n.style.position = "";
n.style.top = "";
n.style.left = "";
n.style.bottom = "";
n.style.right = "";
},
padding: 300,
quality: 1,
});
const link = document.createElement("a");
link.download = "screenshot.png";
link.href = dataUrl;
link.click();
};

Вы можете использовать modern-screenshot напрямую или недавно выпущенный snapdom. Если вы сталкиваетесь с неполными скриншотами (в основном неполные резюме и соединительные линии), вы можете настроить --map-padding в cssVar.

import { snapdom } from "@zumer/snapdom";
const dl2 = async () => {
const result = await snapdom(mind.nodes);
await result.download({ format: "jpg", filename: "my-capture" });
};
Mind Elixir map-padding

Если вы все еще получаете частичные скриншоты, это может быть из-за того, что масштаб не равен 1. Попробуйте установить масштаб в 1 перед созданием скриншота, затем восстановите исходный размер после.

TIP

Попробуйте на CodePen: https://codepen.io/ssshooter/pen/NPqZXXB

Использование с фреймворками серверного рендеринга

При использовании Mind Elixir в фреймворках серверного рендеринга, таких как Next.js, вы часто будете сталкиваться с проблемами типа window is not defined. Это происходит потому, что Mind Elixir сильно зависит от различных DOM операций и не может работать правильно в SSR средах.

Чтобы решить эту проблему, вы можете использовать useEffect для загрузки Mind Elixir во время клиентского рендеринга. Вот простой пример:

"use client";
import { useEffect } from "react";
import { mindMapExample } from "./mapExample";
export const MindMap = ({ className }: { className: string }) => {
useEffect(() => {
import("mind-elixir").then((MindElixir) => {
const theme = MindElixir.default.DARK_THEME;
theme.cssVar["--bgcolor"] = "rgba(0,0,0,0)";
const mei = new MindElixir.default({
el: "#map",
direction: 2,
theme,
});
mei.init({
nodeData: mindMapExample,
});
mei.toCenter();
window.addEventListener("resize", () => {
mei.toCenter();
});
});
}, []);
return (
<div id="wrapper" className={className}>
<div
id="map"
className="pointer-events-none h-[50vh] w-screen"
onScroll={(e) => e.preventDefault()}
></div>
</div>
);
};

Другие опции Mind Elixir

Mind Elixir имеет множество других настраиваемых опций:

interface Options {
// ...
direction?: number; // Направление расположения узлов: 0 слева, 1 справа, 2 с обеих сторон
locale?: Locale; // Выбор языка
contextMenu?: boolean | ContextMenuOption; // Включить контекстное меню, можно добавить опции
toolBar?: boolean; // Включить встроенную панель инструментов
keypress?: boolean | KeypressOptions; // Включить горячие клавиши, можно добавить пользовательские горячие клавиши
mouseSelectionButton?: 0 | 2; // Кнопка перетаскивания, по умолчанию правый клик
before?: Before; // Перехват операций, упомянутый выше
newTopicName?: string; // Значение по умолчанию для новых узлов
allowUndo?: boolean; // Включить отмену/повтор
overflowHidden?: boolean; // Может ли холст двигаться, полезно для карточек ментальных карт
alignment?: Alignment; // Когда установлено в 'nodes', холст центрируется на ментальной карте; когда 'root', центрируется на корневом узле (по умолчанию)
scaleSensitivity?: number; // Чувствительность масштабирования для колеса прокрутки и меню
draggable?: boolean; // Можно ли перетаскивать узлы
editable?: boolean; // Можно ли редактировать
// ...
}

Заключение

Через это руководство вы теперь должны освоить техники Mind Elixir от базового использования до продвинутой настройки. Если вы столкнетесь с какими-либо проблемами во время использования, или у вас есть лучшие идеи и предложения, не стесняйтесь делиться в комментариях или присоединяйтесь к обсуждению на GitHub и отправляйте PR! Давайте сделаем Mind Elixir еще лучше вместе!

评论组件加载中……