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

Открытое JavaScript ядро ментальных карт Mind Elixir предлагает следующие ключевые возможности:
- Плавный пользовательский опыт Плавные взаимодействия с естественной обратной связью, включая поддержку мобильных устройств.
- Легковесность и высокая производительность Небольшой размер с быстрой загрузкой и рендерингом, поддержание высокой частоты кадров даже при сложных диаграммах.
- Независимость от фреймворков Легкая интеграция с React, Vue, Svelte или vanilla проектами — работает автономно или встраивается.
- Архитектура плагинов Гибкая система плагинов, поддерживающая официальные расширения и пользовательские плагины для модульной функциональности.
- Поддержка экспорта PNG / HTML Экспорт ментальных карт как изображений или HTML-страниц для легкого обмена и встраивания.
- Резюме узлов и соединения Поддержка резюме узлов, соединительных линий, тегов и различных стилей узлов для удовлетворения разных потребностей.
- Поддержка отмены / повтора Полный стек истории операций — любое изменение можно быстро отменить или повторить с уверенностью.
- Эффективные горячие клавиши Богатые горячие клавиши для повышения продуктивности опытных пользователей.
- Настройка CSS переменных Легкое управление стилями узлов и общими темами через CSS переменные для высоко настраиваемых, красивых макетов.
Давайте разберем, как быстро интегрировать Mind Elixir в ваши проекты! 🤗
Супер простая интеграция
Установите зависимость:
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
может настроить расстояние между основными узлами:

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" });};

Если вы все еще получаете частичные скриншоты, это может быть из-за того, что масштаб не равен 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 еще лучше вместе!