note-graph
Advanced tools
Comparing version 0.1.1 to 0.1.2
@@ -5,2 +5,9 @@ # Changelog | ||
### [0.1.2](https://github.com/hikerpig/note-graph/compare/v0.1.1...v0.1.2) (2020-12-06) | ||
### Features | ||
* fix lessened node and link overlap bug by mixing colors rather than opacity ([a81586e](https://github.com/hikerpig/note-graph/commit/a81586e5371a9d899fda9f3b969b906480ac6fb3)) | ||
### [0.1.1](https://github.com/hikerpig/note-graph/compare/v0.1.0...v0.1.1) (2020-12-04) | ||
@@ -7,0 +14,0 @@ |
@@ -291,2 +291,15 @@ import { rgb, hsl } from 'd3-color'; | ||
// function mixColorFieldss<T extends HSLColor | RGBColor, K extends keyof T>(color1: T, color2: T, fields: K[], amount=0.5) { | ||
// const results = fields.map((k: any) => { | ||
// return color1[k] * amount + color2[k] * (1 - amount) | ||
// }) | ||
// return results | ||
// } | ||
function mixRgb(color1, color2, amount = 0.5) { | ||
const r = color1.r * amount + color2.r * (1 - amount); | ||
const g = color1.g * amount + color2.g * (1 - amount); | ||
const b = color1.b * amount + color2.b * (1 - amount); | ||
return rgb(r, g, b); | ||
} | ||
const makeDrawWrapper = (ctx) => ({ | ||
@@ -375,2 +388,3 @@ circle: function (x, y, radius, color) { | ||
return; | ||
const backgroundRgb = rgb(this.style.background); | ||
const getNodeColor = (nodeId, model) => { | ||
@@ -389,5 +403,6 @@ const info = model.nodeInfos[nodeId]; | ||
if (!color) { | ||
const c = hsl(typeFill); | ||
c.opacity = 0.2; | ||
color = c; | ||
const c = rgb(typeFill); | ||
// use mixing instead of opacity | ||
const mixedColor = mixRgb(c, backgroundRgb, 0.6); | ||
color = mixedColor; | ||
} | ||
@@ -394,0 +409,0 @@ return { fill: color, border: color }; |
@@ -299,2 +299,15 @@ 'use strict'; | ||
// function mixColorFieldss<T extends HSLColor | RGBColor, K extends keyof T>(color1: T, color2: T, fields: K[], amount=0.5) { | ||
// const results = fields.map((k: any) => { | ||
// return color1[k] * amount + color2[k] * (1 - amount) | ||
// }) | ||
// return results | ||
// } | ||
function mixRgb(color1, color2, amount = 0.5) { | ||
const r = color1.r * amount + color2.r * (1 - amount); | ||
const g = color1.g * amount + color2.g * (1 - amount); | ||
const b = color1.b * amount + color2.b * (1 - amount); | ||
return d3Color.rgb(r, g, b); | ||
} | ||
const makeDrawWrapper = (ctx) => ({ | ||
@@ -383,2 +396,3 @@ circle: function (x, y, radius, color) { | ||
return; | ||
const backgroundRgb = d3Color.rgb(this.style.background); | ||
const getNodeColor = (nodeId, model) => { | ||
@@ -397,5 +411,6 @@ const info = model.nodeInfos[nodeId]; | ||
if (!color) { | ||
const c = d3Color.hsl(typeFill); | ||
c.opacity = 0.2; | ||
color = c; | ||
const c = d3Color.rgb(typeFill); | ||
// use mixing instead of opacity | ||
const mixedColor = mixRgb(c, backgroundRgb, 0.6); | ||
color = mixedColor; | ||
} | ||
@@ -402,0 +417,0 @@ return { fill: color, border: color }; |
/** | ||
* @version 0.1.1 | ||
* @version 0.1.2 | ||
*/ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-color"),require("d3-force"),require("d3-scale"),require("force-graph")):"function"==typeof define&&define.amd?define(["exports","d3-color","d3-force","d3-scale","force-graph"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).NOTE_GRAPH={},e.d3,e.d3,e.d3,e.ForceGraph)}(this,(function(e,t,i,o,n){"use strict";function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=r(n);function h(e,t,i,o){var n,r=!1,s=0;function h(){n&&clearTimeout(n)}function a(){for(var a=arguments.length,d=new Array(a),l=0;l<a;l++)d[l]=arguments[l];var c=this,u=Date.now()-s;function f(){s=Date.now(),i.apply(c,d)}function g(){n=void 0}r||(o&&!n&&f(),h(),void 0===o&&u>e?f():!0!==t&&(n=setTimeout(o?g:f,void 0===o?e-u:e)))}return"boolean"!=typeof t&&(o=i,i=t,t=void 0),a.cancel=function(){h(),r=!0},a}var a=function(e,t,i){return void 0===i?h(e,t,!1):h(e,i,!1!==t)};const d=(e,...t)=>{if(!t.length)return e;const i=t.shift();return void 0===i?e:(l(e)&&l(i)&&Object.keys(i).forEach((function(t){l(i[t])?(e[t]||(e[t]={}),d(e[t],i[t])):e[t]=i[t]})),d(e,...t))},l=e=>(e=>null!==e&&"object"==typeof e)(e)&&!Array.isArray(e);function c(e,t,i){return getComputedStyle(e).getPropertyValue(t)||i}function u(e={}){const t=e.container||document.body,i=c(t,"--notegraph-highlighted-foreground-color","#f9c74f");return{background:c(t,"--notegraph-background","#f7f7f7"),fontSize:parseInt(c(t,"--notegraph-font-size",12)),highlightedForeground:i,node:{note:{regular:c(t,"--notegraph-note-color-regular","#5f76e7")},unknown:c(t,"--notegraph-unkown-node-color","#f94144")},link:{regular:c(t,"--notegraph-link-color-regular","#ccc"),highlighted:c(t,"--notegraph-link-color-highlighted",i)},hoverNodeLink:{highlightedDirection:{inbound:"#3078cd",outbound:i}}}}const f=e=>({circle:function(t,i,o,n){return e.beginPath(),e.arc(t,i,o,0,2*Math.PI,!1),e.fillStyle=n,e.fill(),e.closePath(),this},text:function(t,i,o,n,r){return e.font=`${n}px Sans-Serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=r,e.fillText(t,i,o),this}});e.NoteGraphModel=class{constructor(e){this.subscribers=[],this.notes=e,this.updateCache()}updateCache(){const e=[],t=[],i={},o=new Map;this.notes.forEach((n=>{e.push({id:n.id,data:{note:n}});const r={title:n.title,linkIds:[],neighbors:[]};n.linkTo&&n.linkTo.forEach((e=>{const i={id:this.formLinkId(n.id,e),source:n.id,target:e};t.push(i),o.set(i.id,i),r.linkIds.push(i.id),r.neighbors.push(e)})),n.referencedBy&&n.referencedBy.forEach((e=>{r.linkIds.push(this.formLinkId(e,n.id)),r.neighbors.push(e)})),i[n.id]=r}));const n=this.cache||{};n.nodeInfos=i,n.links=t,n.linkMap=o,this.cache=n}getNodeInfoById(e){return this.cache.nodeInfos[e]}getLinkById(e){return this.cache.linkMap.get(e)}formLinkId(e,t){return`${e}-${t}`}toGraphViewData(){return{graphData:{nodes:this.notes,links:this.cache.links},nodeInfos:this.cache.nodeInfos}}publishChange(){this.subscribers.forEach((e=>{e(this)}))}subscribe(e){return this.subscribers.push(e),()=>{const t=this.subscribers.indexOf(e);t>-1&&this.subscribers.splice(t,1)}}},e.NoteGraphView=class{constructor(e){this.sizeScaler=o.scaleLinear().domain([0,20]).range([1,5]).clamp(!0),this.labelAlphaScaler=o.scaleLinear().domain([1.2,2]).range([0,1]).clamp(!0),this.interactionCallbacks={},this.hasInitialZoomToFit=!1,this.actions={selectNode(e,t,i){i||e.selectedNodes.clear(),null!=t&&e.selectedNodes.add(t)},highlightNode(e,t){e.hoverNode=t}},this.shouldDebugColor=!1,this.options=e,this.container=e.container,this.model={graphData:{nodes:[],links:[]},nodeInfos:{},selectedNodes:new Set,focusNodes:new Set,focusLinks:new Set,hoverNode:null},this.initStyle(),e.graphModel&&(this.linkWithGraphModel(e.graphModel),e.lazyInitView||this.initView())}initStyle(){this.style||(this.style=u({container:this.container})),d(this.style,this.options.style)}updateStyle(e){this.options.style=d(this.options.style||{},e),this.initStyle(),this.refreshByStyle()}refreshByStyle(){if(!this.forceGraph)return;const e=(e,i)=>{const o=i.nodeInfos[e],n=this.style.node.note,r=this.style.node.note[o.type||"regular"]||this.style.node.unknown;switch(this.shouldDebugColor&&console.log("node fill",r),this.getNodeState(e,i)){case"regular":return{fill:r,border:r};case"lessened":let i=n.lessened;if(!i){const e=t.hsl(r);e.opacity=.2,i=e}return{fill:i,border:i};case"highlighted":return{fill:r,border:this.style.highlightedForeground};default:throw new Error(`Unknown type for node ${e}`)}};this.forceGraph.backgroundColor(this.style.background).nodeCanvasObject(((i,o,n)=>{if(!i.id)return;const r=this.model.nodeInfos[i.id],s=this.sizeScaler(r.neighbors?r.neighbors.length:1),{fill:h,border:a}=e(i.id,this.model),d=this.style.fontSize/n;let l=t.rgb(h);const c=this.getNodeState(i.id,this.model),u=this.labelAlphaScaler(n);l.opacity="highlighted"===c?1:"lessened"===c?Math.min(.2,u):u;const g=r.title;f(o).circle(i.x,i.y,s+.5,a).circle(i.x,i.y,s,h).text(g,i.x,i.y+s+1,d,l)})).linkColor((e=>this.getLinkColor(e,this.model)))}linkWithGraphModel(e){this.currentDataModelEntry&&this.currentDataModelEntry.unsub(),this.updateViewData(e.toGraphViewData());const t=e.subscribe((()=>{this.updateViewData(e.toGraphViewData())}));this.currentDataModelEntry={graphModel:e,unsub:t}}getColorOnContainer(e,t){return getComputedStyle(this.container).getPropertyValue(e)||t}updateViewData(e){Object.assign(this.model,e),e.focusedNode&&(this.model.hoverNode=e.focusedNode)}updateCanvasSize(e){this.forceGraph&&("width"in e&&this.forceGraph.width(e.width),"height"in e&&this.forceGraph.height(e.height))}initView(){const{options:e,model:t,style:o,actions:n}=this,r=s.default||globalThis.ForceGraph,h=this.forceGraph||r(),a=e.width||window.innerWidth-this.container.offsetLeft-20,d=e.height||window.innerHeight-this.container.offsetTop-20;h(this.container).height(d).width(a).graphData(t.graphData).linkHoverPrecision(8).enableNodeDrag(!!e.enableNodeDrag).cooldownTime(200).d3Force("x",i.forceX()).d3Force("y",i.forceY()).d3Force("collide",i.forceCollide(h.nodeRelSize())).linkWidth(1).linkDirectionalParticles(1).linkDirectionalParticleWidth((e=>"highlighted"===this.getLinkState(e,t)?2:0)).onEngineStop((()=>{this.hasInitialZoomToFit||(this.hasInitialZoomToFit=!0,h.zoomToFit(1e3,20))})).onNodeHover((e=>{n.highlightNode(this.model,e?.id),this.updateViewModeInteractiveState()})).onNodeClick(((e,t)=>{n.selectNode(this.model,e.id,t.getModifierState("Shift")),this.updateViewModeInteractiveState(),this.fireInteraction("nodeClick",{node:e,event:t})})).onLinkClick(((e,t)=>{this.fireInteraction("linkClick",{link:e,event:t})})).onBackgroundClick((e=>{n.selectNode(this.model,null,e.getModifierState("Shift")),this.updateViewModeInteractiveState(),this.fireInteraction("backgroundClick",{event:e})})).onBackgroundRightClick((e=>{h.zoomToFit(1e3,20),this.fireInteraction("backgroundRightClick",{event:e})})),!1!==e.enableSmartZooming&&this.initGraphSmartZooming(h),this.forceGraph=h,this.refreshByStyle()}initGraphSmartZooming(e){let t=!1;const i=a(200,(e=>{if(t)return;const{x:i,y:o}=this.forceGraph.getGraphBbox(),{k:n,x:r,y:s}=e,h=n*i[0],a=n*i[1],d=n*o[0],l=n*o[1],c=this.forceGraph.width(),u=this.forceGraph.height(),f=this.forceGraph.centerAt();let g,p;a+r<0?(t=!1,g=i[1]):h+r>c&&(g=i[0]),d+s>u?p=o[0]:l+s<0&&(p=o[1]),"number"!=typeof g&&"number"!=typeof p||this.forceGraph.centerAt(void 0!==g?g:f.x,void 0!==p?p:f.y,2e3)}));e.onZoom((e=>{this.hasInitialZoomToFit&&i(e)})).onZoomEnd((()=>{setTimeout((()=>{t=!1}),20)}))}getLinkNodeId(e){const t=typeof e;return"string"===t||"number"===t?e:e.id}getNodeState(e,t=this.model){return t.selectedNodes.has(e)||t.hoverNode===e?"highlighted":0===t.focusNodes.size||t.focusNodes.has(e)?"regular":"lessened"}getLinkState(e,t=this.model){return 0===t.focusNodes.size?"regular":t.focusLinks.has(e.id)?"highlighted":"lessened"}getLinkColor(e,i){const o=this.style,n=o.link;switch(this.getLinkState(e,i)){case"regular":return n.regular;case"highlighted":let r;const s=o.hoverNodeLink;return i.hoverNode===this.getLinkNodeId(e.source)?r=s.highlightedDirection?.outbound:i.hoverNode===this.getLinkNodeId(e.target)&&(r=s.highlightedDirection?.inbound),r||n.highlighted||o.highlightedForeground;case"lessened":let h=n.lessened;if(!h){const e=t.hsl(o.node.note.lessened);e.opacity=.2,h=e}return h;default:throw new Error(`Unknown type for link ${e}`)}}updateViewModeInteractiveState(){const{model:e}=this,t=new Set,i=new Set;if(e.hoverNode){t.add(e.hoverNode);const o=e.nodeInfos[e.hoverNode];o.neighbors?.forEach((e=>t.add(e))),o.linkIds?.forEach((e=>i.add(e)))}e.selectedNodes&&e.selectedNodes.forEach((o=>{t.add(o);const n=e.nodeInfos[o];n.neighbors?.forEach((e=>t.add(e))),n.linkIds?.forEach((e=>i.add(e)))})),e.focusNodes=t,e.focusLinks=i}setSelectedNodes(e,t=!1){t||this.model.selectedNodes.clear(),e.forEach((e=>this.actions.selectNode(this.model,e,!0))),this.updateViewModeInteractiveState()}onInteraction(e,t){this.interactionCallbacks[e]||(this.interactionCallbacks[e]=[]);const i=this.interactionCallbacks[e];return i.push(t),()=>{const e=i.indexOf(t);e>-1&&i.splice(e,1)}}fireInteraction(e,t){const i=this.interactionCallbacks[e];i&&i.forEach((e=>e(t)))}dispose(){this.forceGraph&&this.forceGraph.pauseAnimation()}},e.getColorOnContainer=c,e.getDefaultColorOf=u,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-color"),require("d3-force"),require("d3-scale"),require("force-graph")):"function"==typeof define&&define.amd?define(["exports","d3-color","d3-force","d3-scale","force-graph"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).NOTE_GRAPH={},e.d3,e.d3,e.d3,e.ForceGraph)}(this,(function(e,t,i,o,n){"use strict";function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=r(n);function h(e,t,i,o){var n,r=!1,s=0;function h(){n&&clearTimeout(n)}function a(){for(var a=arguments.length,d=new Array(a),l=0;l<a;l++)d[l]=arguments[l];var c=this,u=Date.now()-s;function f(){s=Date.now(),i.apply(c,d)}function g(){n=void 0}r||(o&&!n&&f(),h(),void 0===o&&u>e?f():!0!==t&&(n=setTimeout(o?g:f,void 0===o?e-u:e)))}return"boolean"!=typeof t&&(o=i,i=t,t=void 0),a.cancel=function(){h(),r=!0},a}var a=function(e,t,i){return void 0===i?h(e,t,!1):h(e,i,!1!==t)};const d=(e,...t)=>{if(!t.length)return e;const i=t.shift();return void 0===i?e:(l(e)&&l(i)&&Object.keys(i).forEach((function(t){l(i[t])?(e[t]||(e[t]={}),d(e[t],i[t])):e[t]=i[t]})),d(e,...t))},l=e=>(e=>null!==e&&"object"==typeof e)(e)&&!Array.isArray(e);function c(e,t,i){return getComputedStyle(e).getPropertyValue(t)||i}function u(e={}){const t=e.container||document.body,i=c(t,"--notegraph-highlighted-foreground-color","#f9c74f");return{background:c(t,"--notegraph-background","#f7f7f7"),fontSize:parseInt(c(t,"--notegraph-font-size",12)),highlightedForeground:i,node:{note:{regular:c(t,"--notegraph-note-color-regular","#5f76e7")},unknown:c(t,"--notegraph-unkown-node-color","#f94144")},link:{regular:c(t,"--notegraph-link-color-regular","#ccc"),highlighted:c(t,"--notegraph-link-color-highlighted",i)},hoverNodeLink:{highlightedDirection:{inbound:"#3078cd",outbound:i}}}}const f=e=>({circle:function(t,i,o,n){return e.beginPath(),e.arc(t,i,o,0,2*Math.PI,!1),e.fillStyle=n,e.fill(),e.closePath(),this},text:function(t,i,o,n,r){return e.font=`${n}px Sans-Serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=r,e.fillText(t,i,o),this}});e.NoteGraphModel=class{constructor(e){this.subscribers=[],this.notes=e,this.updateCache()}updateCache(){const e=[],t=[],i={},o=new Map;this.notes.forEach((n=>{e.push({id:n.id,data:{note:n}});const r={title:n.title,linkIds:[],neighbors:[]};n.linkTo&&n.linkTo.forEach((e=>{const i={id:this.formLinkId(n.id,e),source:n.id,target:e};t.push(i),o.set(i.id,i),r.linkIds.push(i.id),r.neighbors.push(e)})),n.referencedBy&&n.referencedBy.forEach((e=>{r.linkIds.push(this.formLinkId(e,n.id)),r.neighbors.push(e)})),i[n.id]=r}));const n=this.cache||{};n.nodeInfos=i,n.links=t,n.linkMap=o,this.cache=n}getNodeInfoById(e){return this.cache.nodeInfos[e]}getLinkById(e){return this.cache.linkMap.get(e)}formLinkId(e,t){return`${e}-${t}`}toGraphViewData(){return{graphData:{nodes:this.notes,links:this.cache.links},nodeInfos:this.cache.nodeInfos}}publishChange(){this.subscribers.forEach((e=>{e(this)}))}subscribe(e){return this.subscribers.push(e),()=>{const t=this.subscribers.indexOf(e);t>-1&&this.subscribers.splice(t,1)}}},e.NoteGraphView=class{constructor(e){this.sizeScaler=o.scaleLinear().domain([0,20]).range([1,5]).clamp(!0),this.labelAlphaScaler=o.scaleLinear().domain([1.2,2]).range([0,1]).clamp(!0),this.interactionCallbacks={},this.hasInitialZoomToFit=!1,this.actions={selectNode(e,t,i){i||e.selectedNodes.clear(),null!=t&&e.selectedNodes.add(t)},highlightNode(e,t){e.hoverNode=t}},this.shouldDebugColor=!1,this.options=e,this.container=e.container,this.model={graphData:{nodes:[],links:[]},nodeInfos:{},selectedNodes:new Set,focusNodes:new Set,focusLinks:new Set,hoverNode:null},this.initStyle(),e.graphModel&&(this.linkWithGraphModel(e.graphModel),e.lazyInitView||this.initView())}initStyle(){this.style||(this.style=u({container:this.container})),d(this.style,this.options.style)}updateStyle(e){this.options.style=d(this.options.style||{},e),this.initStyle(),this.refreshByStyle()}refreshByStyle(){if(!this.forceGraph)return;const e=t.rgb(this.style.background),i=(i,o)=>{const n=o.nodeInfos[i],r=this.style.node.note,s=this.style.node.note[n.type||"regular"]||this.style.node.unknown;switch(this.shouldDebugColor&&console.log("node fill",s),this.getNodeState(i,o)){case"regular":return{fill:s,border:s};case"lessened":let o=r.lessened;if(!o){o=function(e,i,o=.5){const n=e.r*o+i.r*(1-o),r=e.g*o+i.g*(1-o),s=e.b*o+i.b*(1-o);return t.rgb(n,r,s)}(t.rgb(s),e,.6)}return{fill:o,border:o};case"highlighted":return{fill:s,border:this.style.highlightedForeground};default:throw new Error(`Unknown type for node ${i}`)}};this.forceGraph.backgroundColor(this.style.background).nodeCanvasObject(((e,o,n)=>{if(!e.id)return;const r=this.model.nodeInfos[e.id],s=this.sizeScaler(r.neighbors?r.neighbors.length:1),{fill:h,border:a}=i(e.id,this.model),d=this.style.fontSize/n;let l=t.rgb(h);const c=this.getNodeState(e.id,this.model),u=this.labelAlphaScaler(n);l.opacity="highlighted"===c?1:"lessened"===c?Math.min(.2,u):u;const g=r.title;f(o).circle(e.x,e.y,s+.5,a).circle(e.x,e.y,s,h).text(g,e.x,e.y+s+1,d,l)})).linkColor((e=>this.getLinkColor(e,this.model)))}linkWithGraphModel(e){this.currentDataModelEntry&&this.currentDataModelEntry.unsub(),this.updateViewData(e.toGraphViewData());const t=e.subscribe((()=>{this.updateViewData(e.toGraphViewData())}));this.currentDataModelEntry={graphModel:e,unsub:t}}getColorOnContainer(e,t){return getComputedStyle(this.container).getPropertyValue(e)||t}updateViewData(e){Object.assign(this.model,e),e.focusedNode&&(this.model.hoverNode=e.focusedNode)}updateCanvasSize(e){this.forceGraph&&("width"in e&&this.forceGraph.width(e.width),"height"in e&&this.forceGraph.height(e.height))}initView(){const{options:e,model:t,style:o,actions:n}=this,r=s.default||globalThis.ForceGraph,h=this.forceGraph||r(),a=e.width||window.innerWidth-this.container.offsetLeft-20,d=e.height||window.innerHeight-this.container.offsetTop-20;h(this.container).height(d).width(a).graphData(t.graphData).linkHoverPrecision(8).enableNodeDrag(!!e.enableNodeDrag).cooldownTime(200).d3Force("x",i.forceX()).d3Force("y",i.forceY()).d3Force("collide",i.forceCollide(h.nodeRelSize())).linkWidth(1).linkDirectionalParticles(1).linkDirectionalParticleWidth((e=>"highlighted"===this.getLinkState(e,t)?2:0)).onEngineStop((()=>{this.hasInitialZoomToFit||(this.hasInitialZoomToFit=!0,h.zoomToFit(1e3,20))})).onNodeHover((e=>{n.highlightNode(this.model,e?.id),this.updateViewModeInteractiveState()})).onNodeClick(((e,t)=>{n.selectNode(this.model,e.id,t.getModifierState("Shift")),this.updateViewModeInteractiveState(),this.fireInteraction("nodeClick",{node:e,event:t})})).onLinkClick(((e,t)=>{this.fireInteraction("linkClick",{link:e,event:t})})).onBackgroundClick((e=>{n.selectNode(this.model,null,e.getModifierState("Shift")),this.updateViewModeInteractiveState(),this.fireInteraction("backgroundClick",{event:e})})).onBackgroundRightClick((e=>{h.zoomToFit(1e3,20),this.fireInteraction("backgroundRightClick",{event:e})})),!1!==e.enableSmartZooming&&this.initGraphSmartZooming(h),this.forceGraph=h,this.refreshByStyle()}initGraphSmartZooming(e){let t=!1;const i=a(200,(e=>{if(t)return;const{x:i,y:o}=this.forceGraph.getGraphBbox(),{k:n,x:r,y:s}=e,h=n*i[0],a=n*i[1],d=n*o[0],l=n*o[1],c=this.forceGraph.width(),u=this.forceGraph.height(),f=this.forceGraph.centerAt();let g,p;a+r<0?(t=!1,g=i[1]):h+r>c&&(g=i[0]),d+s>u?p=o[0]:l+s<0&&(p=o[1]),"number"!=typeof g&&"number"!=typeof p||this.forceGraph.centerAt(void 0!==g?g:f.x,void 0!==p?p:f.y,2e3)}));e.onZoom((e=>{this.hasInitialZoomToFit&&i(e)})).onZoomEnd((()=>{setTimeout((()=>{t=!1}),20)}))}getLinkNodeId(e){const t=typeof e;return"string"===t||"number"===t?e:e.id}getNodeState(e,t=this.model){return t.selectedNodes.has(e)||t.hoverNode===e?"highlighted":0===t.focusNodes.size||t.focusNodes.has(e)?"regular":"lessened"}getLinkState(e,t=this.model){return 0===t.focusNodes.size?"regular":t.focusLinks.has(e.id)?"highlighted":"lessened"}getLinkColor(e,i){const o=this.style,n=o.link;switch(this.getLinkState(e,i)){case"regular":return n.regular;case"highlighted":let r;const s=o.hoverNodeLink;return i.hoverNode===this.getLinkNodeId(e.source)?r=s.highlightedDirection?.outbound:i.hoverNode===this.getLinkNodeId(e.target)&&(r=s.highlightedDirection?.inbound),r||n.highlighted||o.highlightedForeground;case"lessened":let h=n.lessened;if(!h){const e=t.hsl(o.node.note.lessened);e.opacity=.2,h=e}return h;default:throw new Error(`Unknown type for link ${e}`)}}updateViewModeInteractiveState(){const{model:e}=this,t=new Set,i=new Set;if(e.hoverNode){t.add(e.hoverNode);const o=e.nodeInfos[e.hoverNode];o.neighbors?.forEach((e=>t.add(e))),o.linkIds?.forEach((e=>i.add(e)))}e.selectedNodes&&e.selectedNodes.forEach((o=>{t.add(o);const n=e.nodeInfos[o];n.neighbors?.forEach((e=>t.add(e))),n.linkIds?.forEach((e=>i.add(e)))})),e.focusNodes=t,e.focusLinks=i}setSelectedNodes(e,t=!1){t||this.model.selectedNodes.clear(),e.forEach((e=>this.actions.selectNode(this.model,e,!0))),this.updateViewModeInteractiveState()}onInteraction(e,t){this.interactionCallbacks[e]||(this.interactionCallbacks[e]=[]);const i=this.interactionCallbacks[e];return i.push(t),()=>{const e=i.indexOf(t);e>-1&&i.splice(e,1)}}fireInteraction(e,t){const i=this.interactionCallbacks[e];i&&i.forEach((e=>e(t)))}dispose(){this.forceGraph&&this.forceGraph.pauseAnimation()}},e.getColorOnContainer=c,e.getDefaultColorOf=u,Object.defineProperty(e,"__esModule",{value:!0})})); |
{ | ||
"name": "note-graph", | ||
"description": "a generic visualization tool designed to show the structure of the document space and the relations between each doc", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"scripts": { | ||
@@ -6,0 +6,0 @@ "bootstrap": "lerna bootstrap", |
@@ -12,9 +12,9 @@ # Welcome to note-graph 👋 | ||
Inspired by [Foam](https://github.com/foambubble/foam). | ||
[![](https://i.loli.net/2020/12/04/pw5WJDlkhYsMgA2.png)](https://note-graph.vercel.app/) | ||
## Demo and docs 🚀 | ||
## 🚀 Demo and docs | ||
See the [demo](http://note-graph.vercel.app/) on vercel. | ||
See the [demo](https://note-graph.vercel.app/) on vercel. | ||
## Features ✨ | ||
## ✨ Features | ||
@@ -24,6 +24,7 @@ - Display bidirectional links with an elegant yet informative way. | ||
- Hover on the node to see it's link flow. | ||
- Right click on the background to make the graph auto-fits the canvas size, easier to find contents when panning and scrolling makes you lost in the view. | ||
- Right click on the background to make the graph auto-fits the canvas size. | ||
- Smart zooming, prevent you from getting lost when panning and scrolling. | ||
- 🎨 Highly customizable, pick your favorite colors for <del>all</del> (not yet but closing to it) the visual elements. | ||
## Usage | ||
## 📦 Usage | ||
@@ -105,2 +106,6 @@ ### (1) Use in html | ||
## Acknowledgement | ||
- Inspired by [Foam](https://github.com/foambubble/foam). | ||
## Show your support | ||
@@ -107,0 +112,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
76326
14
1569
115