mindoc
mindoc copied to clipboard
思维导图实现(很笨的办法)
一、增加按钮
<a href="javascript:;" data-toggle="tooltip" data-title="流程图/组织架构图/思维导图"><i class="fa fa-sitemap item" name="mindmap" unselectable="on"></i></a>
增加一个div,用于按钮帮助
<div style="display:none;" id="mindmaphelp">
>[warning]mindmap 参数说明:
语法:描述写在` ```mindmap` 和` ``` `之间
各`选项`用“选项名”:“选项值”分开,各选项间用空格分割
`size:`指定显示流程图的大小,可选值为“mindmap-sm”、“mindmap-md”、“mindmap-lg”
`Theme:`流程图主题,可选项为:“classic”、“classic-compact”、“fish”、“fresh-blue”、“fresh-blue-compat”、“fresh-green”、“fresh-green-compat”、“fresh-pink”、“fresh-pink-compat”、“fresh-purple”、“fresh-purple-compat”、“fresh-red”、“fresh-red-compat”、“fresh-soil”、“fresh-soil-compat”、“snow”、“snow-compact”、“tianpan”、“tianpan-compact”、“wire”,默认值为“fresh-blue”。
`Template:`流程图模板,支持“default”、"fresh-blue"、“filetree”、"fish-bone"、“right”、“structure”、“tianpan”,默认值为"fresh-blue"。
`protocol:`指定的用于解析数据的数据协议(默认内置三种数据协议 “json”、“text” 和 “markdown”的支持),改造后,支持markdown中的“list”写法,如`- 根节点`,一共四种支持。
`tmpshow`这个参数主要用于显示输入原始数据,建议使用list写法的时候开启,默认隐藏,只支持"true"。
```mindmap size:mindmap-md Theme:fresh-blue Template:default protocol:markdown tmpshow:false
``` 二、按钮方法
else if (name=="mindmap"){//流程图说明
var cm = window.editor.cm;
var selection = cm.getSelection();
var cursor = cm.getCursor();
if (selection === "") {
cm.replaceSelection("\n"+$("#mindmaphelp").text() + selection+"\n\n");
cm.setCursor(cursor.line+11, 0);
cm. focus() ;
}else {
var selectionText = selection.split("\n");
for (var i = 0, len = selectionText.length; i < len; i++) {
selectionText[i] = (selectionText[i] === "") ? "" : $("#mindmaphelp").text() + selectionText[i];
}
cm.replaceSelection(selectionText.join("\n\n"));
cm.setCursor(cursor.line+11, 0);
cm. focus() ;
}
}
三、引入百度的kityminder.core.min.js和kity.min.js,引入自已写的mindmap.min.js
// 将 li 节点转换为 JSON 数据
function li2jsonData(liNode) {
var liData;
var aNode = liNode.children("a:first");
if (aNode.length !== 0) {
liData = {
"data": {
"text": aNode.text(),
"hyperlink": aNode.attr("href")
}
};
} else {
liData = {
"data": {
"text": liNode[0].childNodes[0].nodeValue.trim()
}
};
}
liNode.find("> ul > li").each(function() {
if (!liData.hasOwnProperty("children")) {
liData.children = [];
}
liData.children.push(li2jsonData($(this)));
});
return liData;
}
function drawMindMap(div) {
//各参数解析开始
var lang = $(div).find(".mindmapoption").text();
var sizeps = lang.match(/(?<=size:)(mindmap-sm|mindmap-md|mindmap-lg)(?= )/i);
var Templateps = lang.match(/(?<=Template:)(fresh-blue|filetree|fish-bone|right|structure|tianpan)(?= )/i);
var Themeps = lang.match(/(?<=Theme:)(classic|classic-compact|fish|fresh-blue|fresh-blue-compat|fresh-green|fresh-green-compat|fresh-pink|fresh-pink-compat|fresh-purple|fresh-purple-compat|fresh-red|fresh-red-compat|fresh-soil|fresh-soil-compat|snow|snow-compact|tianpan|tianpan-compact|wire)(?= )/i);
var protocolps = lang.match(/(?<=protocol:)(json|text|markdown|list)(?= )/i);
var tmpshowps = lang.match(/(?<=tmpshow:)(true)(?= )/i);
var size = (sizeps !== null) ? sizeps[0] : "mindmap-md";
var Theme = (Themeps !== null) ? Themeps[0] : "default";
var protocol = (protocolps !== null) ? protocolps[0] : "markdown";
var Template = (Templateps !== null) ? Templateps[0] : "default";
var tmpshow = (tmpshowps !== null) ? "": "style=\"display:none;\"";
//参数解析结束
var markdownText = $(div).find(".mindmaptmp").text().trim();
if (protocol == "list") {
var ulElement = $(div).find(".mindmaptmp").find(">ul:first");
var mmData = {
"root": {}
};
var minder = new kityminder.Minder({
renderTo: div
});
try {
mmData.root = li2jsonData(ulElement.children("li:first"));
mmData.template = Template;
mmData.theme = Theme;
minder.importData('json', JSON.stringify(mmData));
minder.disable();
/* minder.setTemplate(Template);
minder.setTheme(Theme); */
minder.execCommand('hand');
} catch(e) {
console.log(e);
}
$(ulElement).hide();
} else {
var minder = new kityminder.Minder({
renderTo: div
});
var markdownText = $(div).find(".mindmaptmp").text().trim();
try {
minder.importData('json', markdownText);
minder.disable();
//以下两句,在运行时没什么效果,包含useTemplate
/*minder.setTemplate(Template);
minder.setTheme(Theme); */
minder.execCommand('hand');
} catch(e) {
console.log(e);
}
}
}
四、修改editor.md的代码块
markedRenderer.code = function (code, lang, escaped) {
if (lang === "seq" || lang === "sequence")
{
return "<div class=\"sequence-diagram\">" + code + "</div>";
}
else if ( lang === "flow")
{
return "<div class=\"flowchart\">" + code + "</div>";
}
else if ( lang === "math" || lang === "latex" || lang === "katex")
{
return "<p class=\"" + editormd.classNames.tex + "\">" + code + "</p>";
}
else if (/^mindmap/i.test(lang))
{
lang=lang+" ";//加一个空格,便于解析各参数使用
//各参数解析开始
var sizeps = lang.match(/(?<=size:)(mindmap-sm|mindmap-md|mindmap-lg)(?= )/i);
var Templateps = lang.match(/(?<=Template:)(fresh-blue|filetree|fish-bone|right|structure|tianpan)(?= )/i);
var Themeps = lang.match(/(?<=Theme:)(classic|classic-compact|fish|fresh-blue|fresh-blue-compat|fresh-green|fresh-green-compat|fresh-pink|fresh-pink-compat|fresh-purple|fresh-purple-compat|fresh-red|fresh-red-compat|fresh-soil|fresh-soil-compat|snow|snow-compact|tianpan|tianpan-compact|wire)(?= )/i);
var protocolps=lang.match(/(?<=protocol:)(json|text|markdown|list)(?= )/i);
var tmpshowps=lang.match(/(?<=tmpshow:)(true)(?= )/i);
var size=(sizeps!== null)?sizeps[0]:"mindmap-md";
var Theme=(Themeps!== null)?Themeps[0]:"fresh-blue";
var protocol=(protocolps!== null)?protocolps[0]:"markdown";
var Template=(Templateps!== null)?Templateps[0]:"default";
var tmpshow=(tmpshowps!== null)?"":"style=\"display:none;\"";
//参数解析结束
//生成两个div,其中一个存放参数,一个存放待生成的数据。
if(protocol=="list"){
code=marked(code);
}else {
//先将code解析为json数据,并添加主题和模板,如果不先解析,按照官方文档,使用minder.execCommand('Template', "right");或minder.useTemplate;minder.setTemplate;等均没有效果,需要单独添加一个按钮或标签,等加载完才可以改变,有点无语。
var minder=new kityminder.Minder();
try {
var tmpcode = minder.decodeData(protocol,code);
tmpcode=tmpcode.fulfillValue;
tmpcode.template=Template;
tmpcode.theme=Theme;
code=JSON.stringify(tmpcode);
}catch(e)
{
}}
var mindmapoption="<div class=\"mindmapoption\" style=\"display:none;\" >" + lang + "</div>";
var midmaptmpdiv="<div class=\"mindmaptmp\"" +tmpshow+" >" + code + "</div>";
return "<div class=\"mindmap "+size+"\">"+mindmapoption+midmaptmpdiv+"</div>";
}
else
{
return marked.Renderer.prototype.code.apply(this, arguments);
}
};
五、在flowChartAndSequenceDiagramRender中去解析
try {
$('.mindmap').each(function() {
drawMindMap(this);
});
} catch (e) {
console.log(e);
}
六、前台阅读界面,在加载完成后,再去解析一次,否则图不能拖动。
七、css文件
.km-view {
font-family: "STHeitiSC-Light", "STHeiti", "Hei", "Heiti SC", "Microsoft Yahei", Arial, sans-serif;
-webkit-user-select: none;
user-select: none;
position: relative;
}
.km-view .km-receiver {
position: absolute;
left: -99999px;
top: -99999px;
width: 20px;
height: 20px;
outline: none;
margin: 0;
}
.km-view image {
cursor: zoom-in;
}
.km-image-viewer {
position: fixed;
z-index: 99999;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, .75);
}
.km-image-viewer .km-image-viewer-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
text-align: center;
white-space: nowrap;
overflow: auto;
}
.km-image-viewer .km-image-viewer-container::before {
content: '';
display: inline-block;
height: 100%;
width: 0;
font-size: 0;
vertical-align: middle;
}
.km-image-viewer .km-image-viewer-container img {
cursor: zoom-out;
vertical-align: middle;
}
.km-image-viewer .km-image-viewer-container img.limited {
cursor: zoom-in;
max-width: 100%;
max-height: 100%;
}
.km-image-viewer .km-image-viewer-toolbar {
z-index: 1;
background: rgba(0, 0, 0, .75);
text-align: right;
transition: all .25s;
}
.km-image-viewer .km-image-viewer-toolbar.hidden {
transform: translate(0, -100%);
opacity: 0;
}
.km-image-viewer .km-image-viewer-btn {
cursor: pointer;
outline: 0;
border: 0;
width: 44px;
height: 44px;
background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjY0IiBoZWlnaHQ9Ijg4IiB2aWV3Qm94PSIwIDAgMjY0IDg4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZT5kZWZhdWx0LXNraW4gMjwvdGl0bGU+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48Zz48cGF0aCBkPSJNNjcuMDAyIDU5LjV2My43NjhjLTYuMzA3Ljg0LTkuMTg0IDUuNzUtMTAuMDAyIDkuNzMyIDIuMjItMi44MyA1LjU2NC01LjA5OCAxMC4wMDItNS4wOThWNzEuNUw3MyA2NS41ODUgNjcuMDAyIDU5LjV6IiBpZD0iU2hhcGUiIGZpbGw9IiNmZmYiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTMgMjl2LTVoMnYzaDN2MmgtNXpNMTMgMTVoNXYyaC0zdjNoLTJ2LTV6TTMxIDE1djVoLTJ2LTNoLTN2LTJoNXpNMzEgMjloLTV2LTJoM3YtM2gydjV6IiBpZD0iU2hhcGUiLz48L2c+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTYyIDI0djVoLTJ2LTNoLTN2LTJoNXpNNjIgMjBoLTV2LTJoM3YtM2gydjV6TTcwIDIwdi01aDJ2M2gzdjJoLTV6TTcwIDI0aDV2MmgtM3YzaC0ydi01eiIvPjwvZz48cGF0aCBkPSJNMjAuNTg2IDY2bC01LjY1Ni01LjY1NiAxLjQxNC0xLjQxNEwyMiA2NC41ODZsNS42NTYtNS42NTYgMS40MTQgMS40MTRMMjMuNDE0IDY2bDUuNjU2IDUuNjU2LTEuNDE0IDEuNDE0TDIyIDY3LjQxNGwtNS42NTYgNS42NTYtMS40MTQtMS40MTRMMjAuNTg2IDY2eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xMTEuNzg1IDY1LjAzTDExMCA2My41bDMtMy41aC0xMHYtMmgxMGwtMy0zLjUgMS43ODUtMS40NjhMMTE3IDU5bC01LjIxNSA2LjAzeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNTIuMjE1IDY1LjAzTDE1NCA2My41bC0zLTMuNWgxMHYtMmgtMTBsMy0zLjUtMS43ODUtMS40NjhMMTQ3IDU5bDUuMjE1IDYuMDN6IiBmaWxsPSIjZmZmIi8+PGc+PHBhdGggaWQ9IlJlY3RhbmdsZS0xMSIgZmlsbD0iI2ZmZiIgZD0iTTE2MC45NTcgMjguNTQzbC0zLjI1LTMuMjUtMS40MTMgMS40MTQgMy4yNSAzLjI1eiIvPjxwYXRoIGQ9Ik0xNTIuNSAyN2MzLjAzOCAwIDUuNS0yLjQ2MiA1LjUtNS41cy0yLjQ2Mi01LjUtNS41LTUuNS01LjUgMi40NjItNS41IDUuNSAyLjQ2MiA1LjUgNS41IDUuNXoiIGlkPSJPdmFsLTEiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTUwIDIxaDV2MWgtNXoiLz48L2c+PGc+PHBhdGggZD0iTTExNi45NTcgMjguNTQzbC0xLjQxNCAxLjQxNC0zLjI1LTMuMjUgMS40MTQtMS40MTQgMy4yNSAzLjI1eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xMDguNSAyN2MzLjAzOCAwIDUuNS0yLjQ2MiA1LjUtNS41cy0yLjQ2Mi01LjUtNS41LTUuNS01LjUgMi40NjItNS41IDUuNSAyLjQ2MiA1LjUgNS41IDUuNXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTA2IDIxaDV2MWgtNXoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTA5LjA0MyAxOS4wMDhsLS4wODUgNS0xLS4wMTcuMDg1LTV6Ii8+PC9nPjwvZz48L2c+PC9zdmc+");
}
.km-image-viewer .km-image-viewer-toolbar {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.km-image-viewer .km-image-viewer-close {
background-position: 0 -44px;
}
.mindmap {
width: inherit;
border: 1px solid #ccc;
}
.mindmap-sm {
height: 300px;
}
.mindmap-md {
height: 500px;
}
.mindmap-lg {
height: 800px;
}
解决问题的方法,用 PR 通知作者会比较好。
https://github.com/pandao/editor.md/issues/790 是否考虑加入导入word文档和支持从office文档粘贴转换为markdown的功能?
https://github.com/mindoc-org/mindoc/issues/603 按照这个方式可以。另外,本身它就支持mermaid各种思维导图
graph TD
B["fa:fa-twitter for peace"]
B-->C[fa:fa-ban forbidden]
B-->D(fa:fa-spinner);