diff options
-rw-r--r-- | components/config.ts | 6 | ||||
-rw-r--r-- | components/tweaks.tsx | 45 | ||||
-rw-r--r-- | org-roam-ui.el | 14 | ||||
-rw-r--r-- | pages/index.tsx | 41 |
4 files changed, 92 insertions, 14 deletions
diff --git a/components/config.ts b/components/config.ts index 0544b58..5cc7775 100644 --- a/components/config.ts +++ b/components/config.ts @@ -34,6 +34,7 @@ export const initialPhysics = { export const initialFilter = { orphans: false, parents: true, + fileless_cites: false, tags: [], nodes: [], links: [], @@ -86,6 +87,11 @@ export const initialVisuals = { citeGapLength: 15, citeLinkColor: 'gray.600', citeNodeColor: 'black', + refDashes: true, + refDashLength: 35, + refGapLength: 15, + refLinkColor: 'gray.200', + refNodeColor: 'black', } export interface TagColors { diff --git a/components/tweaks.tsx b/components/tweaks.tsx index cb1fec0..ff7054f 100644 --- a/components/tweaks.tsx +++ b/components/tweaks.tsx @@ -233,6 +233,15 @@ export const Tweaks = (props: TweakProps) => { isChecked={filter.parents} ></Switch> </Flex> + <Flex justifyContent="space-between"> + <Text>Citations without note files</Text> + <Switch + onChange={() => { + setFilter({ ...filter, fileless_cites: !filter.fileless_cites }) + }} + isChecked={filter.fileless_cites} + ></Switch> + </Flex> </VStack> <Accordion padding={0} allowToggle allowMultiple paddingLeft={3}> <AccordionItem> @@ -762,6 +771,42 @@ export const Tweaks = (props: TweakProps) => { value={'citeLinkColor'} visValue={visuals.citeLinkColor} /> + + <EnableSection + label="Dash ref links" + infoText="Add dashes to citation links, whose target has a note, made with org-roam-bibtex" + value={visuals.refDashes} + onChange={() => setVisuals({ ...visuals, refDashes: !visuals.refDashes })} + > + <SliderWithInfo + label="Dash length" + value={visuals.refDashLength / 10} + onChange={(value) => + setVisuals({ ...visuals, refDashLength: value * 10 }) + } + /> + <SliderWithInfo + label="Gap length" + value={visuals.refGapLength / 5} + onChange={(value) => setVisuals({ ...visuals, refGapLength: value * 5 })} + /> + </EnableSection> + <ColorMenu + colorList={colorList} + label="Reference node color" + visuals={visuals} + setVisuals={setVisuals} + value={'refNodeColor'} + visValue={visuals.refNodeColor} + /> + <ColorMenu + colorList={colorList} + label="Referencelink color" + visuals={visuals} + setVisuals={setVisuals} + value={'refLinkColor'} + visValue={visuals.refLinkColor} + /> <Box> <Flex alignItems="center" justifyContent="space-between"> <Text>Labels</Text> diff --git a/org-roam-ui.el b/org-roam-ui.el index 5ac7eac..368d788 100644 --- a/org-roam-ui.el +++ b/org-roam-ui.el @@ -157,6 +157,9 @@ This serves the web-build and API over HTTP." (org-roam-ui--send-graphdata)) ) +(defun org-roam-ui--create-fake-node (ref) + (list ref ref ref 0 `(("ROAM_REFS" . ,(format "cite:%s" ref)) ("FILELESS" . t)) 'nil)) + (defun org-roam-ui--send-graphdata () "Get roam data, make JSON, send through websocket to org-roam-ui." (let* ((nodes-columns [id file title level properties ,(funcall group-concat tag (emacsql-escape-raw \, ))]) @@ -174,14 +177,17 @@ This serves the web-build and API over HTTP." :from links :left :outer :join refs :on (= links:dest refs:ref) :where (or (= links:type "id") (= links:type "cite"))])) - ;; Convert any cite links that have nodes with associated refs to a - ;; standard id link while removing the 'nil `refs:node-id' from all - ;; other links + ;; Convert any cite links that have nodes with associated refs to an + ;; id based link of type `ref' while removing the 'nil `refs:node-id' + ;; from all other links (links-db-rows (seq-map (lambda (l) (pcase-let ((`(,source ,dest ,type ,node-id) l)) (if node-id - (list source node-id "cite") + (list source node-id "ref") (list source dest type)))) links-db-rows)) + (links-with-empty-refs (seq-filter (lambda (l) (equal (nth 2 l) "cite")) links-db-rows)) + (fake-nodes (delete-dups (seq-map (lambda (l) (org-roam-ui--create-fake-node (nth 1 l))) links-with-empty-refs))) + (nodes-db-rows (append nodes-db-rows fake-nodes)) (response `((nodes . ,(mapcar (apply-partially #'org-roam-ui-sql-to-alist (append nodes-names nil)) nodes-db-rows)) (links . ,(mapcar (apply-partially #'org-roam-ui-sql-to-alist '(source target type)) links-db-rows)) (tags . ,(seq-mapcat #'seq-reverse (org-roam-db-query [:select :distinct tag :from tags])))))) diff --git a/pages/index.tsx b/pages/index.tsx index 9e46f45..7d947e0 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -70,6 +70,14 @@ export default function Home() { return <GraphPage /> } +function normalizeLinkEnds(link: OrgRoamLink | LinkObject): [string, string] { + // we need to cover both because force-graph modifies the original data + // but if we supply the original data on each render, the graph will re-render sporadically + const sourceId = typeof link.source === 'object' ? (link.source.id! as string) : (link.source as string) + const targetId = typeof link.target === 'object' ? (link.target.id! as string) : (link.target as string) + return [sourceId, targetId] +} + export function GraphPage() { const [physics, setPhysics] = usePersistantState('physics', initialPhysics) const [filter, setFilter] = usePersistantState('filter', initialFilter) @@ -416,6 +424,9 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) { if (filter.tags.length && node.tags.length) { return !filter.tags.some((tag) => node.tags.indexOf(tag) > -1) } + if (filter.fileless_cites && node.properties.FILELESS) { + return false + } if (!filter.orphans) { return true @@ -434,14 +445,16 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) { const filteredNodeIds = filteredNodes.map((node) => node.id as string) const filteredLinks = graphData.links.filter((link) => { - if (filter.tags.length) { - const sourceId = typeof link.source === 'object' ? link.source.id! : (link.source as string) - const targetId = typeof link.target === 'object' ? link.target.id! : (link.target as string) - return ( + const [sourceId, targetId] = normalizeLinkEnds(link) + if ( + !( filteredNodeIds.includes(sourceId as string) && filteredNodeIds.includes(targetId as string) ) + ) { + return false } + const linkRoam = link as OrgRoamLink return filter.parents || linkRoam.type !== 'parent' }) @@ -464,8 +477,7 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) { const scopedLinks = filteredGraphData.filteredLinks.filter((link) => { // we need to cover both because force-graph modifies the original data // but if we supply the original data on each render, the graph will re-render sporadically - const sourceId = typeof link.source === 'object' ? link.source.id! : (link.source as string) - const targetId = typeof link.target === 'object' ? link.target.id! : (link.target as string) + const [sourceId, targetId] = normalizeLinkEnds(link) return ( scopedNodeIds.includes(sourceId as string) && scopedNodeIds.includes(targetId as string) ) @@ -651,9 +663,12 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) { const tagColor = tagColors[node.tags.filter((tag) => tagColors[tag])[0]] return getThemeColor(tagColor) } - if (visuals.citeNodeColor && node.properties.ROAM_REFS) { + if (visuals.citeNodeColor && node.properties.ROAM_REFS && node.properties.FILELESS) { return getThemeColor(visuals.citeNodeColor) } + if (visuals.refNodeColor && node.properties.ROAM_REFS) { + return getThemeColor(visuals.refNodeColor) + } if (!needsHighlighting) { return getThemeColor(getNodeColorById(node.id as string)) } @@ -783,6 +798,9 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) { const linkWasHighlighted = isLinkRelatedToNode(link, lastHoverNode.current) const needsHighlighting = linkIsHighlighted || linkWasHighlighted const roamLink = link as OrgRoamLink + if (visuals.refLinkColor && roamLink.type === 'ref') { + return getThemeColor(visuals.refLinkColor) + } if (visuals.citeLinkColor && roamLink.type === 'cite') { return getThemeColor(visuals.citeLinkColor) } @@ -870,10 +888,13 @@ export const Graph = forwardRef(function (props: GraphProps, graphRef: any) { {...graphCommonProps} linkLineDash={(link) => { const linkArg = link as OrgRoamLink - if (!visuals.citeDashes || linkArg.type !== 'cite') { - return null + if (visuals.citeDashes && linkArg.type === 'cite') { + return [visuals.citeDashLength, visuals.citeGapLength] + } + if (visuals.refDashes && linkArg.type == 'ref') { + return [visuals.refDashLength, visuals.refGapLength] } - return [visuals.citeDashLength, visuals.citeGapLength] + return null }} /> )} |