chart = {
const svg = d3.create("svg")
.attr("font-size", "11pt")
.attr("viewBox", [0, 0, width, height]);
const markerSize = 5;
const markerBoxWidth = markerSize;
const markerBoxHeight = markerSize;
const refX = markerBoxWidth / 2;
const refY = markerBoxHeight / 2;
const markerWidth = markerBoxWidth / 2;
const markerHeight = markerBoxHeight / 2;
const arrowPoints = [[0, 0], [0, markerSize], [markerSize, markerSize / 2]];
var defs = svg.append("defs");
var linerGradient = defs.append("linearGradient")
.attr("id","linearColor")
.attr("x1","0%")
.attr("y1","0%")
.attr("x2","100%")
.attr("y2","0%");
var stop1 = linerGradient.append("stop")
.attr("offset","0%")
.attr("stop-color","#b34689")
.attr("stop-opacity",0.75);
var stop2 = linerGradient.append("stop")
.attr("offset","100%")
.attr("stop-color","#b34689")
.attr("stop-opacity",0);
var linerGradient2 = defs.append("linearGradient")
.attr("id","linearColor2")
.attr("gradientUnits","userSpaceOnUse")
.attr("x1","100%")
.attr("y1","50%")
.attr("x2","100%")
.attr("y2","0%");
var stop2_1 = linerGradient2.append("stop")
.attr("offset","0%")
.attr("stop-color","#fff")
.attr("stop-opacity",0.75);
var stop2_2 = linerGradient2.append("stop")
.attr("offset","100%")
.attr("stop-color","#000")
.attr("stop-opacity",0);
var arrowMarker = defs
.append('marker')
.attr("markerUnits", "strokeWidth")
.attr('markerWidth', 6)
.attr('markerHeight', 6)
.attr('id', 'arrow')
.attr('viewBox', "0, -5, 10, 10")
.attr('refX', '8')
.attr('refY', '2')
.attr('orient', 'auto')
.append('path')
.attr('d', d3.line()(arrowPoints))
.attr('fill', "#b34689");
const arcs = svg.append('g')//arcs:由结点出发的圆弧
.selectAll("path")
.data(graph.links)
.join("path")
.attr("fill", "none")
.attr("stroke", "#ccc")
.attr('stroke-opacity', 0)
.attr("stroke-width", d => 2)
.attr("d", arc)
.on("mouseover", highlight)
.on("mouseout", restore);
const arcs2 = svg.append('g')//arcs2:指向结点的圆弧
.selectAll("path")
.data(graph.links)
.join("path")
.attr("fill", "none")
.attr("stroke", "#ccc")
.attr('stroke-opacity', 0)
.attr("stroke-width", d => 2)
.attr("d", arc2)
.on("mouseover", highlight)
.on("mouseout", restore);
//年份的直线
for(var i=0;i<graph.nodes.length-1;i++){
var currentYear=graph.nodes[i].year;
var nextYear = graph.nodes[i+1].year;
let scale = d3.scaleLinear().domain([currentYear,nextYear]).range([xScale(graph.nodes[i].idx),xScale(graph.nodes[i+1].idx)]);
for(var j=currentYear;j<=nextYear;j++){
var positionX=scale(j);
svg.append("line")
.attr("x1",function(d){
return positionX;
})
.attr("y1",baseHeight)
.attr("x2",function(d){
return positionX;
})
.attr("y2",50)
.attr("stroke","#000")
.attr("stroke","url(#"+linerGradient2.attr("id")+")")
.attr("stroke-width",0.5);
}
}
//年份标注
for(var i=0;i<graph.nodes.length-1;i++){
var currentYear=graph.nodes[i].year;
var nextYear = graph.nodes[i+1].year;
let scale = d3.scaleLinear().domain([currentYear,nextYear]).range([xScale(graph.nodes[i].idx),xScale(graph.nodes[i+1].idx)]);
for(var j=currentYear;j<nextYear;j++){
var positionX=scale(j);
svg.append("g")
.append("text")
.attr("text-anchor", "start")
.attr('font-size', 7)
.attr('font-family', 'sans-serif')
.style('fill',function(d){
if(j%5==0&&j>1940){
console.log("year"+j);
return "#000";
}
else return 'none';
})
.attr("x",positionX-8)
.attr("y",55)
.text(j);
}
}
const circles = svg.selectAll(".node")
.data(graph.nodes)
.join("g")
.attr("class", "node")
.attr("transform", d => `translate(${xScale(d.idx)},${baseHeight})`)
.attr("fill", d=> color(d.name))
circles.append("circle")
.attr("r", d => rScale(d.influence))
.on("mouseover", highlight)
.on("mouseout", restore);
//text背景色
// var backgroundColor = circles.append("rect")
// .attr("width",12)
// .attr("height",function(d){
// var l = d.name.length;
// console.log(d.name.length);
// return l*6;
// })
// .attr("transform", d => `translate(-3,${rScale(d.influence) + 10}) rotate(-45)`)
// .attr("fill","#fff")
//text
var circleText = circles.append("g")
.attr("text-anchor", "start")
.attr('font-size', 10)
.attr('font-family', 'sans-serif')
.attr("transform", d => `translate(0,${rScale(d.influence) + 10}) rotate(45)`)
.call(g => g.append("text").text(d => d.name))
return svg.node();
function highlight(e, d, restore) {
circles.filter(c => c.id===d.id)
.attr("fill", c => restore ? "#ccc" : "#fff")
.attr("stroke", c => restore ? "none" : "#b34689")
.attr("stroke-width", 1.5);
if (d.name) {
arcs.filter(a => a.source === d)//arcs:由结点出发的圆弧
.attr('marker-end', 'url(#arrow)')
.attr('stroke-opacity', d=> restore? 0 : 1)
.attr("stroke", d => restore ? "#ccc" : "#b34689")
.attr("stroke-width", 2);
arcs2.filter(a => a.target === d)//arcs2:指向结点的圆弧
.attr('marker-end', 'none')
.attr('stroke-opacity', d=> restore? 0 : 1)
.attr("stroke","url(#"+linerGradient.attr("id")+")")
.attr("stroke-width",7);
circles.filter(c => hasRelation(c.id, d.id));
circles.filter(c => !hasRelation(c.id, d.id))
.attr("fill", c => restore ? color(c.name) : "#ccc")
.attr('fill-opacity', c => restore ? 1 : 0.5);
}
}
function restore(e, d) {
highlight(e, d, true);
arcs.attr('marker-end', 'none');
arcs2.attr('marker-end', 'none');
}
}