Update modular_graph_and_candidates.py

#1
by sergiopaniego HF Staff - opened
Files changed (1) hide show
  1. modular_graph_and_candidates.py +31 -3
modular_graph_and_candidates.py CHANGED
@@ -960,6 +960,14 @@ const zoomBehavior = d3.zoom()
960
  .on('zoom', handleZoom);
961
  svg.call(zoomBehavior);
962
 
 
 
 
 
 
 
 
 
963
  const g = svg.append('g');
964
 
965
  // Time scale for chronological positioning with much wider spread
@@ -1036,6 +1044,16 @@ const link = g.selectAll('path.link')
1036
  .attr('fill', 'none')
1037
  .attr('stroke-width', d => d.cand ? 2.5 : 1.5);
1038
 
 
 
 
 
 
 
 
 
 
 
1039
  // Nodes with improved positioning strategy
1040
  const node = g.selectAll('g.node')
1041
  .data(timeline.nodes)
@@ -1043,6 +1061,16 @@ const node = g.selectAll('g.node')
1043
  .attr('class', d => `node ${d.cls}`)
1044
  .call(d3.drag().on('start', dragStart).on('drag', dragged).on('end', dragEnd));
1045
 
 
 
 
 
 
 
 
 
 
 
1046
  const baseSel = node.filter(d => d.cls === 'base');
1047
  baseSel.append('circle').attr('r', 20).attr('fill', '#ffbe0b');
1048
  node.filter(d => d.cls !== 'base').append('circle').attr('r', 18);
@@ -1069,10 +1097,10 @@ timeline.nodes.forEach((d, i) => {
1069
  // Enhanced force simulation for optimal horizontal chronological layout
1070
  const sim = d3.forceSimulation(timeline.nodes)
1071
  .force('link', d3.forceLink(timeline.links).id(d => d.id)
1072
- .distance(d => d.cand ? 100 : 200)
1073
  .strength(d => d.cand ? 0.1 : 0.3))
1074
- .force('charge', d3.forceManyBody().strength(-300))
1075
- .force('collide', d3.forceCollide(d => 45).strength(0.8));
1076
 
1077
  // Very strong chronological X positioning for proper horizontal spread
1078
  if (timeScale) {
 
960
  .on('zoom', handleZoom);
961
  svg.call(zoomBehavior);
962
 
963
+ svg.on("click", function(event) {
964
+ if (event.target.tagName === "svg") {
965
+ node.style("opacity", 1);
966
+ link.style("opacity", 1);
967
+ g.selectAll(".node-label").style("opacity", 1);
968
+ }
969
+ });
970
+
971
  const g = svg.append('g');
972
 
973
  // Time scale for chronological positioning with much wider spread
 
1044
  .attr('fill', 'none')
1045
  .attr('stroke-width', d => d.cand ? 2.5 : 1.5);
1046
 
1047
+ const linkedByIndex = {};
1048
+ timeline.links.forEach(d => {
1049
+ linkedByIndex[`${d.source.id},${d.target.id}`] = true;
1050
+ linkedByIndex[`${d.target.id},${d.source.id}`] = true;
1051
+ });
1052
+
1053
+ function isConnected(a, b) {
1054
+ return linkedByIndex[`${a.id},${b.id}`] || a.id === b.id;
1055
+ }
1056
+
1057
  // Nodes with improved positioning strategy
1058
  const node = g.selectAll('g.node')
1059
  .data(timeline.nodes)
 
1061
  .attr('class', d => `node ${d.cls}`)
1062
  .call(d3.drag().on('start', dragStart).on('drag', dragged).on('end', dragEnd));
1063
 
1064
+ node.on("click", function(event, d) {
1065
+ // Stop click from bubbling up to svg
1066
+ event.stopPropagation();
1067
+
1068
+ node.style("opacity", o => isConnected(d, o) ? 1 : 0.1);
1069
+ link.style("opacity", o => (o.source.id === d.id || o.target.id === d.id) ? 1 : 0.1);
1070
+ g.selectAll(".node-label")
1071
+ .style("opacity", o => isConnected(d, o) ? 1 : 0.1);
1072
+ });
1073
+
1074
  const baseSel = node.filter(d => d.cls === 'base');
1075
  baseSel.append('circle').attr('r', 20).attr('fill', '#ffbe0b');
1076
  node.filter(d => d.cls !== 'base').append('circle').attr('r', 18);
 
1097
  // Enhanced force simulation for optimal horizontal chronological layout
1098
  const sim = d3.forceSimulation(timeline.nodes)
1099
  .force('link', d3.forceLink(timeline.links).id(d => d.id)
1100
+ .distance(d => d.cand ? 200 : 300)
1101
  .strength(d => d.cand ? 0.1 : 0.3))
1102
+ .force('charge', d3.forceManyBody().strength(-800))
1103
+ .force('collide', d3.forceCollide(d => 70).strength(1))
1104
 
1105
  // Very strong chronological X positioning for proper horizontal spread
1106
  if (timeScale) {