如何通过更新json数据更新D3 Zoomable旭日形轮视图

时间:2018-03-01 04:54:18

标签: javascript jquery d3.js sunburst-diagram sunburnt

这里我尝试更新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 + '\n' + 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旭日形轮。

请帮帮我。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

我使用了这段代码,它对我很有用..!

setTimeout(function () {d3.selectAll("svg > *").remove(); updateChart(newItems); }, 2000);