如何通过更新json数据更新D3 Zoomable旭日形轮视图
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过更新json数据更新D3 Zoomable旭日形轮视图相关的知识,希望对你有一定的参考价值。
在这里我尝试更新json数据及其D3轮视图,但我不知道为什么它不更新D3 sunbrust并更新数据
这是我的代码//在html正文中
//css code
svg{
width: 100% !important;
background:#ffffff;
}
.slice {
cursor: pointer;
}
.slice .main-arc {
stroke: #fff;
stroke-width: 1px;
}
.slice .hidden-arc {
fill: none;
}
.slice text {
pointer-events: none;
dominant-baseline: middle;
text-anchor: middle;
}
#tooltip { background-color: white;
padding: 3px 5px;
border: 1px solid black;
text-align: center;}
div.tooltip {
position: absolute;
text-align: left;
width: auto;
height: auto;
padding: 8px;
font: 12px sans-serif;
background: #0a2538;
border: #0a2538 1px solid;
border-radius: 0px;
pointer-events: none;
color: white;
}
//D3 Script code for https://d3js.org/d3.v4.min.js
const initItems ={
"name": "Core root",
"id":3,
"description":"Lorem ipsum dolor sit amet",
"children": [
{
"name": "VM.HSN.5.A",
"children": [
{
"name": "eiusmod",
"children": [
{"name": "G.8.1", "id": 5},
{"name": "G.8.2", "id": 4}
]
},
{
"name": "F.8.0",
"children": [
{"name": "F.8.4", "id": 1},
{"name": "F.8.5", "id":1}
]
},
{
"name": "EE.8.5-CLX",
"children": [
{"name": "EE.8.5-CLX2", "id": 1}
]
}
]
},
{
"name": "NS.8.2-CLX",
"children": [
{"name": "NS.8.2-CLX4", "id": 1},
{"name": "NS.8.2-CLX5", "id": 1},
{
"name": "NS.8.0",
"children": [
{"name": "NS.8.2", "id": 1},
{"name": "NS.8.3", "id": 1}
]
},
{"name": "NS.8.1-CLX1", "id":1},
{"name": "NS.8.1-CLX2", "id": 1},
{"name": "NS.8.1-CLX3", "id":1},
{"name": "NS.8.1-CLX4", "id": 1},
{"name": "NS.8.1-CLX5", "id": 1}
]
}
]
}
var newItems = {
"name": "Second Root",
"children": [{
"name": "A2",
"children": [{
"name": "B4",
"size": 40
}, {
"name": "B5",
"size": 30
}, {
"name": "B6",
"size": 10
}]
}, {
"name": "A3",
"children": [{
"name": "B7",
"size": 50
}, {
"name": "B8",
"size": 15
}
]
}]
}
const width = window.innerWidth,
height = window.innerHeight,
maxRadius = (Math.min(width, height) / 2) - 20;
const formatNumber = d3.format(',d');
const x = d3.scaleLinear()
.range([0, 2 * Math.PI])
.clamp(true);
const y = d3.scaleSqrt()
.range([maxRadius*.1, maxRadius]);
const color = d3.scaleOrdinal(d3.schemeCategory20);
const partition = d3.partition();
const arc = d3.arc()
.startAngle(d => x(d.x0))
.endAngle(d => x(d.x1))
.innerRadius(d => Math.max(0, y(d.y0)))
.outerRadius(d => Math.max(0, y(d.y1)));
const middleArcLine = d => {
const halfPi = Math.PI/2;
const angles = [x(d.x0) - halfPi, x(d.x1) - halfPi];
const r = Math.max(0, (y(d.y0) + y(d.y1)) / 2);
const middleAngle = (angles[1] + angles[0]) / 2;
const invertDirection = middleAngle > 0 && middleAngle < Math.PI; // On lower quadrants write text ccw
if (invertDirection) { angles.reverse(); }
const path = d3.path();
path.arc(0, 0, r, angles[0], angles[1], invertDirection);
return path.toString();
};
const textFits = d => {
const CHAR_SPACE = 6;
const deltaAngle = x(d.x1) - x(d.x0);
const r = Math.max(0, (y(d.y0) + y(d.y1)) / 2);
const perimeter = r * deltaAngle;
return d.data.name.length * CHAR_SPACE < perimeter;
};
const svg = d3.select('#vdata').append('svg')
.style('width', '100vw')
.style('height', '100vh')
.attr('viewBox', `${-width / 2} ${-height / 2} ${width} ${height}`)
.on('click', () => focusOn()); // Reset zoom on canvas click
var updateChart = function (items) {
// var root = items;
console.log(items);
//d3.json('dummy4.json', (error, root) => {
///if (error) throw error;
//start custom code
var root = d3.hierarchy(items, function(d) { return d.children })
.sum( function(d) {
if(d.children) {
return 0
} else {
return 2
}
});
//end custom code
//root = d3.hierarchy(root);
//var ad =root.sum(d => d.depth);
//root.sum(d => d.id);
const slice = svg.selectAll('g.slice')
.data(partition(root).descendants());
slice.exit().remove();
const newSlice = slice.enter()
.append('g').attr('class', 'slice')
.on('click', d => {
console.log(d.data.name);
d3.event.stopPropagation();
focusOn(d);
});
newSlice.append('title')
//.text(d => d.data.name + '
' + d.data.id);
//.on("mouseover", mouseover);
newSlice.append('path')
.attr('class', 'main-arc')
.style('fill',colour)
//.style('fill', d => color((d.children ? d : d.parent).data.name))
//console.log(data.id)
.on("mouseover", mouseover)
.on("mouseout", mouseOutArc)
.attr('d', arc);
newSlice.append('path')
.attr('class', 'hidden-arc')
.attr('id', (_, i) => `hiddenArc${i}`)
.attr('d', middleArcLine);
const text = newSlice.append('text')
.attr('display', d => textFits(d) ? null : 'none');
// Add white contour
text.append('textPath')
.attr('startOffset','50%')
.attr('xlink:href', (_, i) => `#hiddenArc${i}` )
.text(function(d) {
return d.data.name;
})
.style('fill', 'none')
.style('stroke', '#fff')
.style('stroke-width', 5)
.style('stroke-linejoin', 'round');
text.append('textPath')
.attr('startOffset','50%')
.attr('xlink:href', (_, i) => `#hiddenArc${i}` )
.text(function(d) {
return d.data.name;
});
//});
}
// tooltip
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
function colour(d) {
//if (d.id==5) {
var colours;
console.log(d.data.id);
if(d.data.id==5)
{
// There is a maximum of two children!
colours ='#b00';
}else if(d.data.name=='Apps'){
colours='#cc0001';
}
else{
colours=color((d.children ? d : d.parent).data.name)
} // L*a*b* might be better here...
// return d3.hsl((a.h + b.h) / 2, a.s * 1.2, a.l / 1.2);
//}
return colours;
}
function mouseover(d) {
d3.select(this).style("cursor", "pointer")
var descript;
if(d.data.description!=null)
{
descript= "<br/><br/>"+d.data.description;
}else{
descript='';
}
tooltip.html(d.data.name + descript)
.style("opacity", 0.8)
.style("left", (d3.event.pageX) + 0 + "px")
.style("top", (d3.event.pageY) - 0 + "px");
}
function mouseOutArc(){
d3.select(this).style("cursor", "default")
tooltip.style("opacity", 0);
}
function focusOn(d = { x0: 0, x1: 1, y0: 0, y1: 1 }) {
// Reset to top-level if no data point specified
const transition = svg.transition()
.duration(750)
.tween('scale', () => {
const xd = d3.interpolate(x.domain(), [d.x0, d.x1]),
yd = d3.interpolate(y.domain(), [d.y0, 1]);
return t => { x.domain(xd(t)); y.domain(yd(t)); };
});
transition.selectAll('path.main-arc')
.attrTween('d', d => () => arc(d));
transition.selectAll('path.hidden-arc')
.attrTween('d', d => () => middleArcLine(d));
transition.selectAll('text')
.attrTween('display', d => () => textFits(d) ? null : 'none');
moveStackToFront(d);
//
function moveStackToFront(elD) {
svg.selectAll('.slice').filter(d => d === elD)
.each(function(d) {
this.parentNode.appendChild(this);
if (d.parent) { moveStackToFront(d.parent); }
})
}
}
updateChart(initItems);
我正在尝试更新json数据并重新生成D3旭日轮,但它不会更新。在开发人员控制台上,它显示更新了json数据,但它没有更新轮中的文本,也没有正确地重新生成D3旭日形轮。
请帮帮我。提前致谢。
答案
我使用这个代码,它对我很有用..!
setTimeout(function () {d3.selectAll("svg > *").remove(); updateChart(newItems); }, 2000);
以上是关于如何通过更新json数据更新D3 Zoomable旭日形轮视图的主要内容,如果未能解决你的问题,请参考以下文章
javascript Zoomable Treemap#d3.v4
如果源 json 更新(添加或删除项目),则动态更新 D3 Sunburst