Skip to content

Commit a096735

Browse files
committed
feat. 优化 记录导图缩放、折叠状态 #62
1 parent 82b4da6 commit a096735

File tree

5 files changed

+97
-35
lines changed

5 files changed

+97
-35
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## 更新日志
22

3+
### v0.4.0 (2025年6月27日)
4+
5+
- 新增:记忆导图折叠状态;
6+
- 改进:记忆导图缩放、平移状态 在一些情况下无效或错误的问题;
7+
38
### v0.3.7 (2025年6月19日)
49

510
- 修复:大纲为空标题时,无法显示的问题;

src/config.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,9 @@ let zh_CN = {
264264
// 模式内部提示10
265265
mode10_allow_pan: "启用拖拽平移",
266266
mode10_allow_zoom: "启用滚轮缩放",
267-
mode10_hint: "在导图内右键暂存当前缩放和平移状态;之后手动保存挂件设置才能持久化保存。",
268-
mode10_reset: "重置缩放和平移",
267+
mode10_hint: "折叠状态将被自动暂存,之后手动保存挂件设置才能持久化保存;<br/>在导图内右键暂存当前缩放和平移状态;之后手动保存挂件设置才能持久化保存。<br/>没有看到任何内容?点击“重置缩放、平移和折叠状态”按钮,然后手动保存挂件设置",
268+
mode10_reset: "重置缩放、平移和折叠状态",
269+
mode10_default_expand_level_hint: "默认展开层级数",
269270
// 模式内部提示12
270271
mode12_doc_num_text: "展示的文档数",
271272
mode12_update_hint: "按照更新时间排列",
@@ -414,8 +415,9 @@ let en_US = {//先当他不存在 We don't fully support English yet.
414415
// markmap
415416
mode10_allow_pan: "Enable Pan",
416417
mode10_allow_zoom: "Enable zoom",
417-
mode10_hint: "Right-click to temporarily save the current zoom and pan state within the mind map. To persistently save it, you need manually save the widget settings. ",
418-
mode10_reset: "Reset pan and scale",
418+
mode10_hint: "The collapse state will be temporarily saved automatically. To make it persistent, please manually save the widget settings.<br/>Right-click inside the mind map to temporarily save the current zoom and pan state. Then manually save the widget settings to persist it.<br/>Not seeing any content? Click the “Reset Zoom, Pan, and Collapse State” button, then manually save the widget settings",
419+
mode10_reset: "Reset Zoom, Pan, and Collapse State",
420+
mode10_default_expand_level_hint: "Default Expand Level",
419421
// hint text in mode
420422
mode12_doc_num_text: "the num of doc",
421423
mode12_update_hint: "Order by update time",

src/listChildDocsClass.js

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,9 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
524524
"allowZoom": false,
525525
"allowPan": false,
526526
"transform": null,
527+
"settingUniqueFlag": "",
528+
"foldStatus": {},
529+
"defaultExpandLevel": 6,
527530
};
528531
timer;
529532
saveEvent = this.saveOnMouseUp.bind(this);
@@ -537,6 +540,8 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
537540
<input type="checkbox" name="mode10_allow_pan" id="mode10_allow_pan">
538541
<span id="mode10_allow_zoom_hint">${language["mode10_allow_zoom"]}</span>
539542
<input type="checkbox" name="mode10_allow_zoom" id="mode10_allow_zoom">
543+
<span id="mode10_default_expand_level_hint">${language["mode10_default_expand_level_hint"]}</span>
544+
<input type="number" min="1" style="width:3em" name="mode10_default_expand_level" id="mode10_default_expand_level" />
540545
<button id="mode10_refit">${language["mode10_reset"]}</button>
541546
<br/>${language["mode10_hint"]}`);
542547
return custom_attr;
@@ -546,17 +551,23 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
546551
logPush("LOAD SETTINGS")
547552
$("#mode10_allow_zoom").prop("checked", modeSettings["allowZoom"]);
548553
$("#mode10_allow_pan").prop("checked", modeSettings["allowPan"]);
554+
$("#mode10_default_expand_level").val(modeSettings["defaultExpandLevel"]);
549555
$("#mode10_refit").click(this.refit.bind(this));
550556
this.modeSettings.transform = modeSettings["transform"];
557+
this.modeSettings.settingUniqueFlag = modeSettings["settingUniqueFlag"];
558+
this.modeSettings.foldStatus = modeSettings["foldStatus"] ?? {};
551559
}
552560
save() {
553561
return {
554562
"allowZoom": $("#mode10_allow_zoom").prop("checked"),
555563
"allowPan": $("#mode10_allow_pan").prop("checked"),
556-
"transform": this.modeSettings.transform
564+
"transform": this.modeSettings.transform,
565+
"settingUniqueFlag": this.modeSettings.settingUniqueFlag,
566+
"foldStatus": this.modeSettings.foldStatus,
567+
"defaultExpandLevel": $("#mode10_default_expand_level").val(),
557568
}
558569
}
559-
oneDocLink(doc, rowCountStack) {
570+
oneDocLink = (doc, rowCountStack) => {
560571
let docName = doc.name;
561572
if (doc.name.indexOf(".sy") >= 0) {
562573
docName = docName.substring(0, docName.length - 3);
@@ -565,7 +576,8 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
565576
return `* ${docName}\n`;
566577
}
567578
// docName = htmlTransferParser(docName);//引用块文本是动态的,不用转义
568-
return `* [${docName}](siyuan://blocks/${doc.id})\n`;
579+
const FOLD_STR = `<!-- markmap: fold -->`;
580+
return `* [${docName}](siyuan://blocks/${doc.id})${this.modeSettings.foldStatus[doc.id] == true ? FOLD_STR : ""}\n`;
569581
}
570582
destory() {
571583
$("#listColumn").prop("disabled", "");
@@ -576,11 +588,22 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
576588
logPush("refit", this.markMapInstance);
577589
$("#innerSetting").css("display", "none");
578590
this.markMapInstance?.fit();
591+
this.modeSettings.transform = null;
592+
this.modeSettings.foldStatus = {};
579593
}
580594
async doUpdate(textString, updateAttr) {
581595
this.observer.disconnect();
582596
document.getElementById("markmap")?.removeEventListener("mouseup", this.saveOnMouseUp);
583597
let widgetAttr = updateAttr.widgetSetting;
598+
// 确认设置项是否变化,变化则不再规整位置等
599+
let resettedConfigFlag = false;
600+
let modeTypeUniqueStr = widgetAttr["listDepth"] + widgetAttr["outlineStartAt"] + widgetAttr["outlineEndAt"] + widgetAttr["targetId"] + widgetAttr["endDocOutline"] + widgetAttr["sortBy"] + widgetAttr["maxListCount"] + widgetAttr["showHiddenDocs"];
601+
if (this.modeSettings.settingUniqueFlag !== modeTypeUniqueStr) {
602+
this.modeSettings.settingUniqueFlag = modeTypeUniqueStr;
603+
this.modeSettings.transform = null;
604+
resettedConfigFlag = true;
605+
this.modeSettings.foldStatus = {};
606+
}
584607
// 匹配移除返回父文档
585608
textString = textString.replace(new RegExp("\\* \\[../\\][^\\n]*\\n"), "");
586609
let tabHeaderElem = window.top.document.querySelector(`li[data-type="tab-header"].item.item--focus .item__text`);
@@ -610,6 +633,9 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
610633
}
611634
}
612635
// textString = `# ${window.top.document.querySelector(`li[data-type="tab-header"].item.item--focus .item__text`).innerText}\n` + textString;
636+
// 确认折叠状态:
637+
638+
613639
document.getElementById("linksContainer").insertAdjacentHTML("beforeend", `<svg id="markmap" style="width: 100%; display: none;"></svg>`);
614640

615641
let transformer = new window.markmap.Transformer();
@@ -620,15 +646,29 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
620646
const { styles, scripts } = transformer.getUsedAssets(features);
621647
if (styles) window.markmap.loadCSS(styles);
622648
if (scripts) window.markmap.loadJS(scripts, { getMarkmap: () => markmap });
623-
const markmapConfig = this.loadMarkmap(root, widgetAttr);
649+
const markmapConfig = this.loadMarkmap(root, widgetAttr, resettedConfigFlag);
624650
if (this.globalConfig.markmapResizeHandlerEnable && !markmapConfig.zoom && !markmapConfig.pan) {
625651
this.observer.observe(window.frameElement.parentElement);
626652
}
627-
document.getElementById("markmap")?.removeEventListener("mousedown", this.saveEvent);
628-
document.getElementById("markmap").addEventListener("mousedown", this.saveEvent);
653+
document.getElementById("markmap")?.removeEventListener("mousedown", this.saveEvent, true);
654+
document.getElementById("markmap").addEventListener("mousedown", this.saveEvent, true);
629655
return 1;
630656
}
631657
saveOnMouseUp(event) {
658+
if (event.button == 0 && event.srcElement?.nodeName == "circle") {
659+
let circleElem = event.srcElement;
660+
let foldFlag = circleElem.getAttribute("fill") === "var(--markmap-circle-open-bg)";
661+
const gElement = circleElem.parentElement;
662+
const foreignObject = gElement.querySelector("foreignObject");
663+
if (foreignObject) {
664+
const aElement = foreignObject.querySelector('a');
665+
if (aElement) {
666+
logPush('链接地址:', aElement.href);
667+
logPush('链接文本:', aElement.textContent);
668+
this.modeSettings.foldStatus[aElement.href.replace("siyuan://blocks/", "")] = foldFlag;
669+
}
670+
}
671+
}
632672
if (event.button !== 2) {
633673
return;
634674
}
@@ -638,7 +678,7 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
638678
logPush("保存transform", this.modeSettings.transform);
639679
}, 100);
640680
}
641-
loadMarkmap(root, widgetAttr) {
681+
loadMarkmap(root, widgetAttr, resettedConfigFlag) {
642682
let markmapElem = document.getElementById("markmap");
643683
markmapElem.innerHTML = "";
644684
markmapElem.style.height = "";
@@ -650,7 +690,10 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
650690
duration: 0,
651691
zoom: $("#mode10_allow_zoom").prop("checked"),
652692
pan: $("#mode10_allow_pan").prop("checked"),
653-
maxWidth: 0};
693+
maxWidth: 0,
694+
autoFit: false,
695+
initialExpandLevel: parseInt($("#mode10_default_expand_level").val()),
696+
};
654697
if (widgetAttr.listDepth != undefined) {
655698
if (widgetAttr.listDepth == 0 || widgetAttr.endDocOutline) {
656699
markmapConfig.maxWidth = $(window.frameElement).innerWidth() / (widgetAttr.listDepth + widgetAttr.outlineDepth);
@@ -678,19 +721,20 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
678721
// this.markMapInstance.fit().then(()=>{
679722

680723
// })
681-
if (this.modeSettings.transform != null) {
682-
let transform = window.d3.zoomTransform(this.markMapInstance.svg.node());
683-
let newTransform = transform.translate(this.modeSettings.transform.x, this.modeSettings.transform.y);
684-
newTransform = newTransform.scale(this.modeSettings.transform.scale, this.modeSettings.transform.scale);
685-
// transform.translate(this.modeSettings.transform.x, this.modeSettings.transform.y);
686-
// transform.scale(this.modeSettings.transform.scale, this.modeSettings.transform.scale);
687-
this.markMapInstance.svg.call(this.markMapInstance.zoom.transform, newTransform);
688-
// this.markMapInstance.svg.call(this.markMapInstance.zoom.translate, this.modeSettings.transform.x, this.modeSettings.transform.y);
689-
// this.markMapInstance.svg.call(this.markMapInstance.zoom.scale, this.modeSettings.transform.scale, this.modeSettings.transform.scale);
690-
// this.markMapInstance.rescale(this.modeSettings.transform.scale);
691-
// this.markMapInstance.g.attr("transform", this.modeSettings.transstr);
692-
}
693-
724+
setTimeout(()=>{
725+
if (this.modeSettings.transform != null && !resettedConfigFlag) {
726+
logPush("Do transform", this.modeSettings.transform);
727+
// 先归位
728+
this.markMapInstance.svg.call(this.markMapInstance.zoom.transform, window.d3.zoomIdentity);
729+
// 调整到上次保存的位置
730+
let transform = window.d3.zoomTransform(this.markMapInstance.svg.node());
731+
let newTransform = transform.translate(this.modeSettings.transform.x, this.modeSettings.transform.y);
732+
newTransform = newTransform.scale(this.modeSettings.transform.scale, this.modeSettings.transform.scale);
733+
this.markMapInstance.svg.call(this.markMapInstance.zoom.transform, newTransform);
734+
} else {
735+
this.markMapInstance.fit();
736+
}
737+
}, 100);
694738
// $("#markmap a").mousedown((event)=>{
695739
// if (event.buttons = 2) {
696740
// // event.preventDefault();
@@ -744,7 +788,7 @@ class MarkmapPrinter extends MarkdownUrlUnorderListPrinter {
744788
let curHeight = entries[0].contentRect.height;
745789
if ((curWidth != this.contentRectCache.width || curHeight != this.contentRectCache.height) &&
746790
(curWidth != 0)) {
747-
this.observerTimeout = setTimeout(this.loadMarkmap.bind(this, this.root, this.widgetAttr), 300);
791+
this.observerTimeout = setTimeout(this.loadMarkmap.bind(this, this.root, this.widgetAttr, false), 300);
748792
this.contentRectCache.width = curWidth;
749793
this.contentRectCache.height = curHeight;
750794
}

static/markmap-lib.js

Lines changed: 10 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)