add event_date column to event_knowledge and event_predictions tables; update related logic in admin panel and augorWorker
This commit is contained in:
parent
8aa10d9bc2
commit
8d259eb4d1
1 changed files with 29 additions and 14 deletions
43
admin.html
43
admin.html
|
|
@ -1390,15 +1390,30 @@ function renderIntelGraph() {
|
||||||
const zoomBehavior = d3.zoom().scaleExtent([0.08, 6]).on('zoom', ev => g.attr('transform', ev.transform));
|
const zoomBehavior = d3.zoom().scaleExtent([0.08, 6]).on('zoom', ev => g.attr('transform', ev.transform));
|
||||||
svg.call(zoomBehavior);
|
svg.call(zoomBehavior);
|
||||||
|
|
||||||
|
// degree map — nodes with many connections need stronger repulsion
|
||||||
|
const degree = {};
|
||||||
|
for (const l of linksCopy) {
|
||||||
|
degree[l.source] = (degree[l.source] || 0) + 1;
|
||||||
|
degree[l.target] = (degree[l.target] || 0) + 1;
|
||||||
|
}
|
||||||
|
const maxDegree = Math.max(...Object.values(degree), 1);
|
||||||
|
|
||||||
const simulation = d3.forceSimulation(nodesCopy)
|
const simulation = d3.forceSimulation(nodesCopy)
|
||||||
.force('link', d3.forceLink(linksCopy).id(d => d.key).distance(d => {
|
.force('link', d3.forceLink(linksCopy).id(d => d.key).distance(d => {
|
||||||
// tracked-tracked links spread wider
|
const src = typeof d.source === 'object' ? d.source.key : d.source;
|
||||||
const bothTracked = typeof d.source === 'object' ? d.source.tracked && d.target.tracked : false;
|
const tgt = typeof d.target === 'object' ? d.target.key : d.target;
|
||||||
return bothTracked ? 220 : 160;
|
const deg = Math.max(degree[src] || 1, degree[tgt] || 1);
|
||||||
|
// busier nodes push their neighbors further away
|
||||||
|
return 180 + deg * 18;
|
||||||
|
}))
|
||||||
|
.force('charge', d3.forceManyBody().strength(d => {
|
||||||
|
const deg = degree[d.key] || 1;
|
||||||
|
return -1400 - deg * 200;
|
||||||
}))
|
}))
|
||||||
.force('charge', d3.forceManyBody().strength(-900))
|
|
||||||
.force('center', d3.forceCenter(width / 2, height / 2))
|
.force('center', d3.forceCenter(width / 2, height / 2))
|
||||||
.force('collide', d3.forceCollide(d => d.tracked ? 52 : 38));
|
// collision radius covers circle + name text below it
|
||||||
|
.force('collide', d3.forceCollide(d => d.tracked ? 72 : 52))
|
||||||
|
.alphaDecay(0.015);
|
||||||
|
|
||||||
|
|
||||||
// links
|
// links
|
||||||
|
|
@ -1408,22 +1423,22 @@ function renderIntelGraph() {
|
||||||
.data(linksCopy)
|
.data(linksCopy)
|
||||||
.join('line')
|
.join('line')
|
||||||
.attr('stroke', '#334155')
|
.attr('stroke', '#334155')
|
||||||
.attr('stroke-width', d => {
|
.attr('stroke-width', d => 1 + Math.pow(d.count / maxCount, 0.55) * 6)
|
||||||
// more dramatic: 1px at count=1, up to 7px at maxCount
|
.attr('stroke-opacity', d => 0.2 + (d.count / maxCount) * 0.7)
|
||||||
return 1 + Math.pow(d.count / maxCount, 0.6) * 6;
|
|
||||||
})
|
|
||||||
.attr('stroke-opacity', d => 0.25 + (d.count / maxCount) * 0.65)
|
|
||||||
.attr('marker-end', 'url(#ig-arrow)');
|
.attr('marker-end', 'url(#ig-arrow)');
|
||||||
|
|
||||||
// edge labels — size and opacity proportional to count
|
// edge labels — only on edges where count >= median, to avoid hub clutter
|
||||||
|
const sortedCounts = linksCopy.map(l => l.count).sort((a, b) => a - b);
|
||||||
|
const medianCount = sortedCounts[Math.floor(sortedCounts.length / 2)] || 1;
|
||||||
|
|
||||||
const linkLabels = linkG.selectAll('text')
|
const linkLabels = linkG.selectAll('text')
|
||||||
.data(linksCopy)
|
.data(linksCopy.filter(l => l.count >= medianCount))
|
||||||
.join('text')
|
.join('text')
|
||||||
.text(d => d.type)
|
.text(d => d.type)
|
||||||
.attr('text-anchor', 'middle')
|
.attr('text-anchor', 'middle')
|
||||||
.attr('font-size', d => 7 + Math.round((d.count / maxCount) * 4))
|
.attr('font-size', d => 8 + Math.round((d.count / maxCount) * 3))
|
||||||
.attr('fill', '#475569')
|
.attr('fill', '#475569')
|
||||||
.attr('opacity', d => 0.4 + (d.count / maxCount) * 0.5)
|
.attr('opacity', d => 0.45 + (d.count / maxCount) * 0.45)
|
||||||
.attr('pointer-events', 'none');
|
.attr('pointer-events', 'none');
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue