Skip to content

Commit 95e5ffa

Browse files
authored
More similarity graph fixes (#168)
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip
1 parent e8d9a5b commit 95e5ffa

File tree

3 files changed

+41
-47
lines changed

3 files changed

+41
-47
lines changed

apps/registry/app/job-similarity/page.js

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -713,10 +713,12 @@ const GraphContainer = ({ dataSource, algorithm }) => {
713713
setLoading(true);
714714
setError(null);
715715
try {
716+
// Check if we're in development environment
717+
const isLocal = process.env.NODE_ENV === 'development';
718+
const limit = isLocal ? 300 : 1500;
719+
716720
const response = await fetch(
717-
`/api/${
718-
dataSource === 'jobs' ? 'job-' : ''
719-
}similarity?limit=250&algorithm=${algorithm}`
721+
`/api/${dataSource === 'jobs' ? 'job-' : ''}similarity?limit=${limit}`
720722
);
721723
if (!response.ok) {
722724
throw new Error('Failed to fetch data');
@@ -730,7 +732,7 @@ const GraphContainer = ({ dataSource, algorithm }) => {
730732
} finally {
731733
setLoading(false);
732734
}
733-
}, [dataSource, algorithm, processData]);
735+
}, [dataSource, processData]);
734736

735737
const processLinks = useCallback(() => {
736738
if (!rawNodes) return;
@@ -794,78 +796,62 @@ const GraphContainer = ({ dataSource, algorithm }) => {
794796
<ForceGraph2D
795797
graphData={graphData}
796798
nodeColor={(node) =>
797-
highlightNodes.has(node) ? '#FF4757' : node.color
799+
highlightNodes.has(node) ? '#ff0000' : node.color
798800
}
799-
nodeCanvasObject={(node, ctx, globalScale) => {
801+
nodeCanvasObject={(node, ctx) => {
800802
// Draw node
801-
const size = node.size * (4 / Math.max(1, globalScale));
802803
ctx.beginPath();
803-
ctx.arc(node.x, node.y, size, 0, 2 * Math.PI);
804-
ctx.fillStyle = highlightNodes.has(node) ? '#FF4757' : node.color;
804+
ctx.arc(node.x, node.y, node.size * 2, 0, 2 * Math.PI);
805+
ctx.fillStyle = highlightNodes.has(node) ? '#ff0000' : node.color;
805806
ctx.fill();
806807

807-
// Add a subtle glow effect
808-
if (highlightNodes.has(node)) {
809-
ctx.shadowColor = '#FF4757';
810-
ctx.shadowBlur = 15;
811-
ctx.strokeStyle = '#FF4757';
812-
ctx.lineWidth = 2;
813-
ctx.stroke();
814-
ctx.shadowBlur = 0;
815-
}
816808
// Only draw label if node is highlighted
817809
if (highlightNodes.has(node)) {
818810
const label = node.id;
819811
const fontSize = Math.max(14, node.size * 1.5);
820812
ctx.font = `${fontSize}px Sans-Serif`;
821-
ctx.textAlign = 'center';
822-
ctx.textBaseline = 'middle';
823-
ctx.fillStyle = '#000';
824-
825-
// Add background to text
826813
const textWidth = ctx.measureText(label).width;
827814
const bckgDimensions = [textWidth, fontSize].map(
828-
(n) => n + fontSize * 0.4
815+
(n) => n + fontSize * 0.2
829816
);
830-
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
817+
818+
// Draw background for label
819+
ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
831820
ctx.fillRect(
832821
node.x - bckgDimensions[0] / 2,
833-
node.y - bckgDimensions[1] / 2,
822+
node.y - bckgDimensions[1] * 2,
834823
bckgDimensions[0],
835824
bckgDimensions[1]
836825
);
837826

827+
// Draw label
828+
ctx.textAlign = 'center';
829+
ctx.textBaseline = 'middle';
838830
ctx.fillStyle = '#000';
839-
ctx.fillText(label, node.x, node.y);
831+
ctx.fillText(label, node.x, node.y - bckgDimensions[1] * 1.5);
840832

841-
// Add count below label
842-
const countLabel = `${node.count} ${
843-
dataSource === 'jobs' ? 'jobs' : 'resumes'
844-
}`;
833+
// Draw count
834+
const countLabel = `(${node.count})`;
845835
const smallerFont = fontSize * 0.7;
846836
ctx.font = `${smallerFont}px Sans-Serif`;
847837
ctx.fillText(countLabel, node.x, node.y - bckgDimensions[1]);
848838
}
849839
}}
850-
nodeRelSize={4}
840+
nodeRelSize={6}
851841
linkWidth={(link) => (highlightLinks.has(link) ? 2 : 1)}
852842
linkColor={(link) =>
853-
highlightLinks.has(link) ? '#FF4757' : '#E5E9F2'
843+
highlightLinks.has(link) ? '#ff0000' : '#cccccc'
854844
}
855-
linkOpacity={0.5}
845+
linkOpacity={0.3}
856846
linkDirectionalParticles={0}
857847
linkDirectionalParticleWidth={2}
858848
onNodeHover={handleNodeHover}
859849
onNodeClick={handleNodeClick}
860850
enableNodeDrag={false}
861-
cooldownTicks={50}
862-
d3AlphaDecay={0.05}
863-
d3VelocityDecay={0.4}
864-
warmupTicks={50}
865-
d3Force={{
866-
collision: 1,
867-
charge: -30,
868-
}}
851+
cooldownTicks={100}
852+
d3AlphaDecay={0.02}
853+
d3VelocityDecay={0.3}
854+
warmupTicks={100}
869855
width={window.innerWidth}
870856
height={window.innerHeight - 32 * 16}
871857
/>

apps/registry/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"axios": "^1.3.6",
3232
"chatgpt": "^5.2.4",
3333
"compromise": "^14.13.0",
34+
"d3-force": "^3.0.0",
3435
"dotenv-cli": "^7.2.1",
3536
"eventsource-parser": "^1.0.0",
3637
"express": "^4.18.2",

pnpm-lock.yaml

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

0 commit comments

Comments
 (0)