Merge branch 'main' of https://huggingface.co/spaces/Molbap/transformers-modular-refactor
Browse files- modular_graph_and_candidates.py +47 -10
modular_graph_and_candidates.py
CHANGED
|
@@ -837,7 +837,7 @@ svg{ width:100vw; height:100vh; }
|
|
| 837 |
pointer-events:none;
|
| 838 |
text-anchor:middle;
|
| 839 |
font-weight:600;
|
| 840 |
-
font-size:
|
| 841 |
paint-order:stroke fill;
|
| 842 |
stroke:var(--outline);
|
| 843 |
stroke-width:3px;
|
|
@@ -894,14 +894,14 @@ svg{ width:100vw; height:100vh; }
|
|
| 894 |
|
| 895 |
.timeline-label {
|
| 896 |
fill: var(--muted);
|
| 897 |
-
font-size:
|
| 898 |
font-weight: 600;
|
| 899 |
text-anchor: middle;
|
| 900 |
}
|
| 901 |
|
| 902 |
.timeline-month-label {
|
| 903 |
fill: var(--muted);
|
| 904 |
-
font-size:
|
| 905 |
font-weight: 400;
|
| 906 |
text-anchor: middle;
|
| 907 |
opacity: 0.7;
|
|
@@ -926,7 +926,7 @@ svg{ width:100vw; height:100vh; }
|
|
| 926 |
position:fixed; top:20px; left:20px;
|
| 927 |
background:rgba(255,255,255,.95);
|
| 928 |
padding:20px 26px; border-radius:12px; border:1.5px solid #e0e0e0;
|
| 929 |
-
font-size:
|
| 930 |
z-index: 100;
|
| 931 |
backdrop-filter: blur(8px);
|
| 932 |
max-width: 280px;
|
|
@@ -962,19 +962,31 @@ document.getElementById('toggleRed').addEventListener('change', updateVisibility
|
|
| 962 |
const timeline = __TIMELINE_DATA__;
|
| 963 |
const W = innerWidth, H = innerHeight;
|
| 964 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 965 |
// Enhanced timeline configuration for maximum horizontal spread
|
| 966 |
const MARGIN = { top: 60, right: 200, bottom: 120, left: 200 };
|
| 967 |
const CONTENT_HEIGHT = H - MARGIN.top - MARGIN.bottom;
|
| 968 |
const VERTICAL_LANES = 4; // Number of horizontal lanes for better organization
|
| 969 |
|
| 970 |
-
|
| 971 |
-
|
| 972 |
const zoomBehavior = d3.zoom()
|
| 973 |
.scaleExtent([0.1, 8])
|
| 974 |
.on('zoom', handleZoom);
|
| 975 |
svg.call(zoomBehavior);
|
| 976 |
|
| 977 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 978 |
|
| 979 |
// Time scale for chronological positioning with much wider spread
|
| 980 |
const timeExtent = d3.extent(timeline.nodes.filter(d => d.timestamp > 0), d => d.timestamp);
|
|
@@ -1066,6 +1078,23 @@ const link = g.selectAll('path.link')
|
|
| 1066 |
.attr('fill', 'none')
|
| 1067 |
.attr('stroke-width', d => d.cand ? 2.5 : 1.5);
|
| 1068 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1069 |
// Nodes with improved positioning strategy
|
| 1070 |
const node = g.selectAll('g.node')
|
| 1071 |
.data(timeline.nodes)
|
|
@@ -1073,6 +1102,14 @@ const node = g.selectAll('g.node')
|
|
| 1073 |
.attr('class', d => `node ${d.cls}`)
|
| 1074 |
.call(d3.drag().on('start', dragStart).on('drag', dragged).on('end', dragEnd));
|
| 1075 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1076 |
const baseSel = node.filter(d => d.cls === 'base');
|
| 1077 |
baseSel.append('circle').attr('r', 20).attr('fill', '#ffbe0b');
|
| 1078 |
node.filter(d => d.cls !== 'base').append('circle').attr('r', 18);
|
|
@@ -1099,10 +1136,10 @@ timeline.nodes.forEach((d, i) => {
|
|
| 1099 |
// Enhanced force simulation for optimal horizontal chronological layout
|
| 1100 |
const sim = d3.forceSimulation(timeline.nodes)
|
| 1101 |
.force('link', d3.forceLink(timeline.links).id(d => d.id)
|
| 1102 |
-
.distance(d => d.cand ?
|
| 1103 |
.strength(d => d.cand ? 0.1 : 0.3))
|
| 1104 |
-
.force('charge', d3.forceManyBody().strength(-
|
| 1105 |
-
.force('collide', d3.forceCollide(d =>
|
| 1106 |
|
| 1107 |
// Very strong chronological X positioning for proper horizontal spread
|
| 1108 |
if (timeScale) {
|
|
|
|
| 837 |
pointer-events:none;
|
| 838 |
text-anchor:middle;
|
| 839 |
font-weight:600;
|
| 840 |
+
font-size:50px;
|
| 841 |
paint-order:stroke fill;
|
| 842 |
stroke:var(--outline);
|
| 843 |
stroke-width:3px;
|
|
|
|
| 894 |
|
| 895 |
.timeline-label {
|
| 896 |
fill: var(--muted);
|
| 897 |
+
font-size: 40px;
|
| 898 |
font-weight: 600;
|
| 899 |
text-anchor: middle;
|
| 900 |
}
|
| 901 |
|
| 902 |
.timeline-month-label {
|
| 903 |
fill: var(--muted);
|
| 904 |
+
font-size: 35px;
|
| 905 |
font-weight: 400;
|
| 906 |
text-anchor: middle;
|
| 907 |
opacity: 0.7;
|
|
|
|
| 926 |
position:fixed; top:20px; left:20px;
|
| 927 |
background:rgba(255,255,255,.95);
|
| 928 |
padding:20px 26px; border-radius:12px; border:1.5px solid #e0e0e0;
|
| 929 |
+
font-size:24px; box-shadow:0 4px 16px rgba(0,0,0,.12);
|
| 930 |
z-index: 100;
|
| 931 |
backdrop-filter: blur(8px);
|
| 932 |
max-width: 280px;
|
|
|
|
| 962 |
const timeline = __TIMELINE_DATA__;
|
| 963 |
const W = innerWidth, H = innerHeight;
|
| 964 |
|
| 965 |
+
// Create SVG with zoom behavior
|
| 966 |
+
const svg = d3.select('#timeline-svg');
|
| 967 |
+
const g = svg.append('g');
|
| 968 |
+
|
| 969 |
// Enhanced timeline configuration for maximum horizontal spread
|
| 970 |
const MARGIN = { top: 60, right: 200, bottom: 120, left: 200 };
|
| 971 |
const CONTENT_HEIGHT = H - MARGIN.top - MARGIN.bottom;
|
| 972 |
const VERTICAL_LANES = 4; // Number of horizontal lanes for better organization
|
| 973 |
|
| 974 |
+
|
| 975 |
+
|
| 976 |
const zoomBehavior = d3.zoom()
|
| 977 |
.scaleExtent([0.1, 8])
|
| 978 |
.on('zoom', handleZoom);
|
| 979 |
svg.call(zoomBehavior);
|
| 980 |
|
| 981 |
+
svg.on("click", function(event) {
|
| 982 |
+
if (event.target.tagName === "svg") {
|
| 983 |
+
node.select("circle").style("opacity", 1);
|
| 984 |
+
link.style("opacity", 1);
|
| 985 |
+
g.selectAll(".node-label").style("opacity", 1);
|
| 986 |
+
}
|
| 987 |
+
});
|
| 988 |
+
|
| 989 |
+
|
| 990 |
|
| 991 |
// Time scale for chronological positioning with much wider spread
|
| 992 |
const timeExtent = d3.extent(timeline.nodes.filter(d => d.timestamp > 0), d => d.timestamp);
|
|
|
|
| 1078 |
.attr('fill', 'none')
|
| 1079 |
.attr('stroke-width', d => d.cand ? 2.5 : 1.5);
|
| 1080 |
|
| 1081 |
+
const linkedByIndex = {};
|
| 1082 |
+
timeline.links.forEach(d => {
|
| 1083 |
+
const s = typeof d.source === 'object' ? d.source.id : d.source;
|
| 1084 |
+
const t = typeof d.target === 'object' ? d.target.id : d.target;
|
| 1085 |
+
linkedByIndex[`${s},${t}`] = true;
|
| 1086 |
+
linkedByIndex[`${t},${s}`] = true;
|
| 1087 |
+
});
|
| 1088 |
+
|
| 1089 |
+
function isConnected(a, b) {
|
| 1090 |
+
return linkedByIndex[`${a.id},${b.id}`] || a.id === b.id;
|
| 1091 |
+
}
|
| 1092 |
+
|
| 1093 |
+
|
| 1094 |
+
function isConnected(a, b) {
|
| 1095 |
+
return linkedByIndex[`${a.id},${b.id}`] || a.id === b.id;
|
| 1096 |
+
}
|
| 1097 |
+
|
| 1098 |
// Nodes with improved positioning strategy
|
| 1099 |
const node = g.selectAll('g.node')
|
| 1100 |
.data(timeline.nodes)
|
|
|
|
| 1102 |
.attr('class', d => `node ${d.cls}`)
|
| 1103 |
.call(d3.drag().on('start', dragStart).on('drag', dragged).on('end', dragEnd));
|
| 1104 |
|
| 1105 |
+
node.on("click", function(event, d) {
|
| 1106 |
+
event.stopPropagation();
|
| 1107 |
+
node.select("circle").style("opacity", o => isConnected(d, o) ? 1 : 0.1);
|
| 1108 |
+
g.selectAll(".node-label").style("opacity", o => isConnected(d, o) ? 1 : 0.1);
|
| 1109 |
+
link.style("opacity", o => (o.source.id === d.id || o.target.id === d.id) ? 1 : 0.1);
|
| 1110 |
+
});
|
| 1111 |
+
|
| 1112 |
+
|
| 1113 |
const baseSel = node.filter(d => d.cls === 'base');
|
| 1114 |
baseSel.append('circle').attr('r', 20).attr('fill', '#ffbe0b');
|
| 1115 |
node.filter(d => d.cls !== 'base').append('circle').attr('r', 18);
|
|
|
|
| 1136 |
// Enhanced force simulation for optimal horizontal chronological layout
|
| 1137 |
const sim = d3.forceSimulation(timeline.nodes)
|
| 1138 |
.force('link', d3.forceLink(timeline.links).id(d => d.id)
|
| 1139 |
+
.distance(d => d.cand ? 200 : 300)
|
| 1140 |
.strength(d => d.cand ? 0.1 : 0.3))
|
| 1141 |
+
.force('charge', d3.forceManyBody().strength(-800))
|
| 1142 |
+
.force('collide', d3.forceCollide(d => 70).strength(1))
|
| 1143 |
|
| 1144 |
// Very strong chronological X positioning for proper horizontal spread
|
| 1145 |
if (timeScale) {
|