mirror of
https://github.com/zadam/trilium.git
synced 2025-10-11 07:56:30 +08:00
chore(react): reintroduce link distance
This commit is contained in:
parent
5efe05490d
commit
0da66617a8
3 changed files with 36 additions and 33 deletions
|
@ -10,19 +10,6 @@ import type ForceGraph from "force-graph";
|
||||||
import type { GraphData, LinkObject, NodeObject } from "force-graph";
|
import type { GraphData, LinkObject, NodeObject } from "force-graph";
|
||||||
import type FNote from "../entities/fnote.js";
|
import type FNote from "../entities/fnote.js";
|
||||||
|
|
||||||
const esc = utils.escapeHtml;
|
|
||||||
|
|
||||||
const TPL = /*html*/`<div class="note-map-widget">
|
|
||||||
<!-- UI for dragging Notes and link force -->
|
|
||||||
|
|
||||||
<button type="button" data-toggle="button" class="btn tn-tool-button" title="${}" data-type="moveable"></button>
|
|
||||||
<input type="range" class="slider" min="1" title="${t("note_map.link-distance")}" max="100" value="40" >
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="note-map-container"></div>
|
|
||||||
</div>`;
|
|
||||||
|
|
||||||
type WidgetMode = "type" | "ribbon";
|
type WidgetMode = "type" | "ribbon";
|
||||||
type Data = GraphData<NodeObject, LinkObject<NodeObject>>;
|
type Data = GraphData<NodeObject, LinkObject<NodeObject>>;
|
||||||
|
|
||||||
|
@ -41,7 +28,6 @@ export default class NoteMapWidget extends NoteContextAwareWidget {
|
||||||
|
|
||||||
constructor(widgetMode: WidgetMode) {
|
constructor(widgetMode: WidgetMode) {
|
||||||
super();
|
super();
|
||||||
this.fixNodes = false; // needed to save the status of the UI element. Is set later in the code
|
|
||||||
this.widgetMode = widgetMode; // 'type' or 'ribbon'
|
this.widgetMode = widgetMode; // 'type' or 'ribbon'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,25 +41,6 @@ export default class NoteMapWidget extends NoteContextAwareWidget {
|
||||||
new ResizeObserver(() => this.setDimensions()).observe(this.$container[0]);
|
new ResizeObserver(() => this.setDimensions()).observe(this.$container[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshWithNote(note: FNote) {
|
|
||||||
this.$widget.show();
|
|
||||||
|
|
||||||
const ForceGraph = (await import("force-graph")).default;
|
|
||||||
this.graph = new ForceGraph(this.$container[0])
|
|
||||||
// Rendering code was here
|
|
||||||
|
|
||||||
let distancevalue = 40; // default value for the link force of the nodes
|
|
||||||
|
|
||||||
this.$widget.find(".fixnodes-type-switcher input").on("change", async (e) => {
|
|
||||||
distancevalue = parseInt(e.target.closest("input")?.value ?? "0");
|
|
||||||
this.graph.d3Force("link")?.distance(distancevalue);
|
|
||||||
|
|
||||||
this.renderData(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.renderData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
this.$container.html("");
|
this.$container.html("");
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import ActionButton from "../react/ActionButton";
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
import link_context_menu from "../../menus/link_context_menu";
|
import link_context_menu from "../../menus/link_context_menu";
|
||||||
import appContext from "../../components/app_context";
|
import appContext from "../../components/app_context";
|
||||||
|
import Slider from "../react/Slider";
|
||||||
|
|
||||||
interface NoteMapProps {
|
interface NoteMapProps {
|
||||||
note: FNote;
|
note: FNote;
|
||||||
|
@ -27,6 +28,8 @@ export default function NoteMap({ note, widgetMode, parentRef }: NoteMapProps) {
|
||||||
const graphRef = useRef<ForceGraph<NodeObject, LinkObject<NodeObject>>>();
|
const graphRef = useRef<ForceGraph<NodeObject, LinkObject<NodeObject>>>();
|
||||||
const containerSize = useElementSize(parentRef);
|
const containerSize = useElementSize(parentRef);
|
||||||
const [ fixNodes, setFixNodes ] = useState(false);
|
const [ fixNodes, setFixNodes ] = useState(false);
|
||||||
|
const [ linkDistance, setLinkDistance ] = useState(40);
|
||||||
|
const notesAndRelationsRef = useRef<NotesAndRelationsData>();
|
||||||
|
|
||||||
// Build the note graph instance.
|
// Build the note graph instance.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -71,11 +74,18 @@ export default function NoteMap({ note, widgetMode, parentRef }: NoteMapProps) {
|
||||||
|
|
||||||
// Set data
|
// Set data
|
||||||
graph.graphData(notesAndRelations);
|
graph.graphData(notesAndRelations);
|
||||||
|
notesAndRelationsRef.current = notesAndRelations;
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => container.replaceChildren();
|
return () => container.replaceChildren();
|
||||||
}, [ note, mapType ]);
|
}, [ note, mapType ]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!graphRef.current || !notesAndRelationsRef.current) return;
|
||||||
|
graphRef.current.d3Force("link")?.distance(linkDistance);
|
||||||
|
graphRef.current.graphData(notesAndRelationsRef.current);
|
||||||
|
}, [ linkDistance ]);
|
||||||
|
|
||||||
// React to container size
|
// React to container size
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!containerSize || !graphRef.current) return;
|
if (!containerSize || !graphRef.current) return;
|
||||||
|
@ -110,6 +120,12 @@ export default function NoteMap({ note, widgetMode, parentRef }: NoteMapProps) {
|
||||||
onClick={() => setFixNodes(!fixNodes)}
|
onClick={() => setFixNodes(!fixNodes)}
|
||||||
frame
|
frame
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Slider
|
||||||
|
min={1} max={100}
|
||||||
|
value={linkDistance} onChange={setLinkDistance}
|
||||||
|
title={t("note_map.link-distance")}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ref={styleResolverRef} class="style-resolver" />
|
<div ref={styleResolverRef} class="style-resolver" />
|
||||||
|
|
20
apps/client/src/widgets/react/Slider.tsx
Normal file
20
apps/client/src/widgets/react/Slider.tsx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
interface SliderProps {
|
||||||
|
value: number;
|
||||||
|
onChange(newValue: number);
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Slider({ onChange, ...restProps }: SliderProps) {
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
className="slider"
|
||||||
|
onChange={(e) => {
|
||||||
|
onChange(e.currentTarget.valueAsNumber);
|
||||||
|
}}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue