Skip to content

Commit 53e4ba7

Browse files
authored
Merge pull request #39 from data-exp-lab/fe-gexf
Fix Bugs
2 parents d1d06e8 + 502e96d commit 53e4ba7

File tree

4 files changed

+58
-94
lines changed

4 files changed

+58
-94
lines changed

backend/app/main.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -474,17 +474,19 @@ def get_unique_repos():
474474
topics_lower = [t.lower() for t in topics]
475475
placeholders = ",".join(["?"] * len(topics_lower))
476476

477-
# Query to get unique repositories that have ANY of the given topics
478-
# Create a single search pattern that matches any of the topics
479-
search_pattern = '%' + '%'.join(topics_lower) + '%'
480-
query = """
477+
# Query to get unique repositories that have ANY of the given topics using exact matching
478+
conditions = []
479+
for topic in topics_lower:
480+
conditions.append(f"LOWER(t.topics) LIKE '%|{topic}|%' OR LOWER(t.topics) LIKE '{topic}|%' OR LOWER(t.topics) LIKE '%|{topic}' OR LOWER(t.topics) = '{topic}'")
481+
482+
query = f"""
481483
SELECT COUNT(DISTINCT r.nameWithOwner) as count
482484
FROM repos r
483485
JOIN repo_topics t ON r.nameWithOwner = t.repo
484-
WHERE LOWER(t.topics) LIKE ?
486+
WHERE ({" OR ".join(conditions)})
485487
"""
486488

487-
result = topic_service.con.execute(query, [search_pattern]).fetchone()
489+
result = topic_service.con.execute(query).fetchone()
488490
count = result[0] if result else 0
489491

490492
return jsonify({

backend/app/services/edge_generation_service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,10 @@ def _get_repos_for_topics(self, topics: List[str]) -> List[Dict]:
212212
topics_lower = [t.lower() for t in topics]
213213
placeholders = ",".join(["?"] * len(topics_lower))
214214

215-
# Create a more flexible search pattern using OR conditions
215+
# Create exact topic matching conditions
216216
conditions = []
217217
for topic in topics_lower:
218-
conditions.append(f"LOWER(t.topics) LIKE '%{topic}%'")
218+
conditions.append(f"LOWER(t.topics) LIKE '%|{topic}|%' OR LOWER(t.topics) LIKE '{topic}|%' OR LOWER(t.topics) LIKE '%|{topic}' OR LOWER(t.topics) = '{topic}'")
219219

220220
query = f"""
221221
WITH matching_repos AS (

backend/app/services/gexf_node_service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ def generate_gexf_nodes_for_topics(self, topics):
7777
WHERE (
7878
"""
7979

80-
# Add each topic as a separate OR condition
80+
# Add each topic as a separate OR condition with exact matching
8181
conditions = []
8282
for topic in topics_lower:
83-
conditions.append(f"LOWER(t.topics) LIKE '%{topic}%'")
83+
conditions.append(f"LOWER(t.topics) LIKE '%|{topic}|%' OR LOWER(t.topics) LIKE '{topic}|%' OR LOWER(t.topics) LIKE '%|{topic}' OR LOWER(t.topics) = '{topic}'")
8484

8585
temp_table_query += " OR ".join(conditions) + ");"
8686
self.con.execute(temp_table_query)

src/views/EdgePanel.tsx

Lines changed: 46 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -115,101 +115,57 @@ const EdgePanel: FC<{ isExpanded: boolean }> = ({ isExpanded }) => {
115115
});
116116
}
117117

118-
// Function to restore original graph without edges
118+
// Function to restore original graph without edges - OPTIMIZED
119119
const restoreOriginalGraph = async (): Promise<void> => {
120120
try {
121-
// Import the necessary functions to reload the graph
122-
const { readGraph, prepareGraph, enrichData } = await import('../lib/data');
123-
124-
// Reload the graph with the original content (no edges)
125-
const rawGraph = await readGraph({
126-
name: graphFile.name,
127-
extension: graphFile.extension,
128-
textContent: graphFile.textContent
129-
});
130-
131-
if (!rawGraph) {
132-
throw new Error("Failed to parse original graph");
133-
}
134-
135-
// Process the graph and create new data
136-
const { graph, hasEdges } = prepareGraph(rawGraph);
137-
138-
// Preserve existing node positions from current graph
121+
// Quick toggle: just remove all edges from current graph
139122
if (data && data.graph) {
140123
const currentGraph = data.graph;
141-
const preservedPositions: Record<string, { x: number; y: number; size: number; color: string; label: string }> = {};
142-
143-
// First, collect all current positions
144-
const currentNodes = currentGraph.nodes();
145-
for (let i = 0; i < currentNodes.length; i++) {
146-
const nodeId = currentNodes[i];
147-
const currentNodeData = currentGraph.getNodeAttributes(nodeId);
148-
preservedPositions[nodeId] = {
149-
x: currentNodeData.x || 0,
150-
y: currentNodeData.y || 0,
151-
size: currentNodeData.size || 5,
152-
color: currentNodeData.color || "#aaa",
153-
label: currentNodeData.label || nodeId
154-
};
155-
}
156124

157-
// Then apply preserved positions to new graph
158-
const newNodes = graph.nodes();
159-
for (let i = 0; i < newNodes.length; i++) {
160-
const nodeId = newNodes[i];
161-
if (preservedPositions[nodeId]) {
162-
const preserved = preservedPositions[nodeId];
163-
graph.setNodeAttribute(nodeId, "x", preserved.x);
164-
graph.setNodeAttribute(nodeId, "y", preserved.y);
165-
graph.setNodeAttribute(nodeId, "size", preserved.size);
166-
graph.setNodeAttribute(nodeId, "color", preserved.color);
167-
graph.setNodeAttribute(nodeId, "label", preserved.label);
168-
}
125+
// Remove all edges
126+
const edges = currentGraph.edges();
127+
for (let i = 0; i < edges.length; i++) {
128+
currentGraph.dropEdge(edges[i]);
169129
}
170-
}
171-
172-
// Create rich data with minimal processing
173-
const richData = enrichData(graph, hasEdges);
174-
175-
// Update the graph data directly
176-
setData(richData);
177-
178-
// Update the graph context
179-
const newNavState = {
180-
...navState,
181-
role: navState.role,
182-
nodeSizeField: undefined, // Reset to default sizing
183-
// Save current edge creation conditions
184-
edgeCreationTopicThreshold: topicThreshold,
185-
edgeCreationContributorThreshold: contributorThreshold,
186-
edgeCreationStargazerThreshold: stargazerThreshold,
187-
edgeCreationEnableTopicLinking: enableTopicLinking,
188-
edgeCreationEnableContributorOverlap: enableContributorOverlap,
189-
edgeCreationEnableSharedOrganization: enableSharedOrganization,
190-
edgeCreationEnableCommonStargazers: enableCommonStargazers,
191-
edgeCreationEnableDependencies: enableDependencies,
192-
};
193-
setNavState(newNavState);
194130

195-
// Notify user of success
196-
notify({
197-
message: "Graph restored to original state without edges",
198-
type: "success"
199-
});
200-
201-
// Notify user that node sizing has been reset
202-
if (navState.nodeSizeField === "pagerank") {
131+
// Update the graph context to reflect no edges
132+
const newNavState = {
133+
...navState,
134+
role: navState.role,
135+
nodeSizeField: undefined, // Reset to default sizing
136+
// Save current edge creation conditions
137+
edgeCreationTopicThreshold: topicThreshold,
138+
edgeCreationContributorThreshold: contributorThreshold,
139+
edgeCreationStargazerThreshold: stargazerThreshold,
140+
edgeCreationEnableTopicLinking: enableTopicLinking,
141+
edgeCreationEnableContributorOverlap: enableContributorOverlap,
142+
edgeCreationEnableSharedOrganization: enableSharedOrganization,
143+
edgeCreationEnableCommonStargazers: enableCommonStargazers,
144+
edgeCreationEnableDependencies: enableDependencies,
145+
};
146+
setNavState(newNavState);
147+
148+
// Notify user of success
203149
notify({
204-
message: "Node sizing has been reset to default since the graph structure was updated.",
205-
type: "info"
150+
message: "All edges removed from graph",
151+
type: "success"
206152
});
153+
154+
// Notify user that node sizing has been reset
155+
if (navState.nodeSizeField === "pagerank") {
156+
notify({
157+
message: "Node sizing has been reset to default since edges were removed.",
158+
type: "info"
159+
});
160+
}
161+
} else {
162+
throw new Error("No graph data available");
207163
}
208164

209165
} catch (error) {
210-
console.error('Error restoring original graph:', error);
166+
console.error('Error removing edges:', error);
211167
notify({
212-
message: "Failed to restore original graph. Please refresh the page.",
168+
message: "Failed to remove edges. Please refresh the page.",
213169
type: "error"
214170
});
215171
}
@@ -400,9 +356,15 @@ const EdgePanel: FC<{ isExpanded: boolean }> = ({ isExpanded }) => {
400356
}
401357
};
402358

403-
// Handle apply button click
359+
// Handle apply button click with debounce
404360
const handleApplyEdgeCreation = () => {
405-
createEdgesViaBackend();
361+
// Prevent rapid clicking
362+
if (isLoading) return;
363+
364+
// Add a small delay to prevent UI lag
365+
setTimeout(() => {
366+
createEdgesViaBackend();
367+
}, 100);
406368
};
407369

408370
return (

0 commit comments

Comments
 (0)