{
const paddingTop = 100
const svg = d3.create("svg")
.attr("width",width)
.attr("height",height)
.attr("viewBox", [0, 0, width*2, height])
.style("font", "10px sans-serif");
const g = svg.append("g")
.attr("transform",`translate(0,${paddingTop})`)
g.append("g")
.call(axisRight)
g.append("g")
.call(axisBottom)
const storyBoard = g.append("g")
.attr("class","storyBoard")
const nodes = storyBoard.selectAll("circle")
.data(circles)
.join("circle")
.attr("class",(d,i) => `detailSid_${bind_edges.idx2sessionId[i] ? bind_edges.idx2sessionId[i] : 'single'}`)
.attr("r",d=>d.r)
.attr("cx",d=>d.x)
.attr("cy",d=>d.y)
.attr("fill","grey")
.attr("opacity",(d,i)=>{
return bind_edges.idx2sessionId[i] ? 0 : 0.7
})
const defs = g.append("defs")
const linearGradients = defs
.selectAll("linearGradient")
.data(edges.filter(v=>v.source !== '-'))
.join("linearGradient")
.attr("id",(d,i)=>`BuReGradient${i}`)
.attr("gradientUnits","userSpaceOnUse") //使用真实坐标定义起点终点
.attr("x1",d=>idx2pos(d.source)[0])
.attr("y1",d=>idx2pos(d.source)[1])
.attr("x2",d=>idx2pos(d.target)[0])
.attr("y2",d=>idx2pos(d.target)[1])
linearGradients.append("stop")
.attr("offset","0%")
.attr("stop-color",d3.interpolateCividis(0))
// linearGradients.append("stop")
// .attr("offset","50%")
// .attr("stop-color",d3.interpolateCividis(0.5))
linearGradients.append("stop")
.attr("offset","100%")
.attr("stop-color",d3.interpolateCividis(1))
/* 未捆绑回复线 */
g.append("g")
.selectAll("path")
.data(edges.filter(v=>v.source !== '-'))
.join("path")
.attr("d",d => {
return dialogs[d.source].role !== dialogs[d.target].role ?
lineCurveTo(idx2pos(d.source),idx2pos(d.target)) : arcTo(d)
}
)
.attr("stroke",(d,i)=>`url(#BuReGradient${i})`)
.attr("opacity",0)
.attr("stroke-width","3")
.attr("stroke-linecap","round")
.attr("fill","none")
.attr("class",d =>{
return `detailSid_${bind_edges.idx2sessionId[d.source] ? bind_edges.idx2sessionId[d.source] : 'single'}`
})
/* 捆绑回复线 */
g.append("g")
.selectAll("path")
.data(bind_edges.edges)
.join("path")
.attr("d", d => CubeBezierTo(d))
.attr("stroke",(d,i)=>d3.color((d3.interpolateSpectral(Math.random(i)))).darker())
.attr("fill","none")
.attr("stroke-width",d => d.weight)
.attr("stroke-opacity","1")
.attr("class",d => {
if(d.type === "trunk")
return `sid_${d.id.split("_")[0]}`
else
return `sid_${bind_edges.idx2sessionId[d.id]}`
})
/* 捆绑子会话发言节点 */
g.append("g")
.selectAll("rect")
.data(bind_edges.squares)
.join("rect")
.attr("x",d => d['start'])
.attr("y",d => yScale(d['role']) - 10)
.attr("height",20)
.attr("width",d => d['end']-d['start'])
.attr("fill-opacity","0.8")
.attr("rx",10)
.attr("ry",10)
.attr("fill","grey")
.attr("class",d => `sid_${d["session_id"]}`)
.on("click",click)
return svg.node()
}