Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在深入到子节点时保持d3树映射的状态_Javascript_Reactjs_D3.js - Fatal编程技术网

Javascript 在深入到子节点时保持d3树映射的状态

Javascript 在深入到子节点时保持d3树映射的状态,javascript,reactjs,d3.js,Javascript,Reactjs,D3.js,我正在开发D3TreemapV5,在该版本中,我需要在每次用户单击时将treemap的状态保存在localstorage中。我的密码在里面 当用户单击顶部父磁贴时,它将向下钻取到子磁贴。当用户重新加载浏览器时,如何在本地存储中保持这种状态,他希望看到向下钻取的子图块 class Treegraph extends React.Component { createTreeChart = () => { const width = 550; const height = 5

我正在开发D3TreemapV5,在该版本中,我需要在每次用户单击时将treemap的状态保存在localstorage中。我的密码在里面 当用户单击顶部父磁贴时,它将向下钻取到子磁贴。当用户重新加载浏览器时,如何在本地存储中保持这种状态,他希望看到向下钻取的子图块

class Treegraph extends React.Component {
  createTreeChart = () => {
    const width = 550;
    const height = 500;
    var paddingAllowance = 2;
    const format = d3.format(",d");
    const checkLowVal = d => {
      console.log("ChecklowVal", d);
      if (d.value < 2) {
        return true;
      }
    };
    const name = d =>
      d
        .ancestors()
        .reverse()
        .map(d => d.data.name)
        .join(" / ");
    function tile(node, x0, y0, x1, y1) {
      d3.treemapBinary(node, 0, 0, width, height);
      for (const child of node.children) {
        child.x0 = x0 + (child.x0 / width) * (x1 - x0);
        child.x1 = x0 + (child.x1 / width) * (x1 - x0);
        child.y0 = y0 + (child.y0 / height) * (y1 - y0);
        child.y1 = y0 + (child.y1 / height) * (y1 - y0);
      }
    }
    const treemap = data =>
      d3.treemap().tile(tile)(
        d3
          .hierarchy(data)
          .sum(d => d.value)
          .sort((a, b) => b.value - a.value)
      );
    const svg = d3
      .select("#chart")
      .append("svg")
      .attr("viewBox", [0.5, -30.5, width, height + 30])
      .style("font", "16px sans-serif");

    const x = d3.scaleLinear().rangeRound([0, width]);
    const y = d3.scaleLinear().rangeRound([0, height]);

    let group = svg.append("g").call(render, treemap(data));

    function render(group, root) {
      const node = group
        .selectAll("g")
        .data(root.children.concat(root))
        .join("g");

      node
        .filter(d => (d === root ? d.parent : d.children))
        .attr("cursor", "pointer")
        .on("click", d => (d === root ? zoomout(root) : zoomin(d)));

      var tool = d3
        .select("body")
        .append("div")
        .attr("class", "toolTip");

      d3.select(window.frameElement).style("height", height - 20 + "px");
      d3.select(window.frameElement).style("width", width - 20 + "px");
      node
        .append("rect")
        .attr("id", d => (d.leafUid = "leaf"))
        .attr("fill", d =>
          d === root ? "#fff" : d.children ? "#045c79" : "#045c79"
        )
        .attr("stroke", "#fff")
        .on("mousemove", function(d) {
          tool.style("left", d3.event.pageX + 10 + "px");
          tool.style("top", d3.event.pageY - 20 + "px");
          tool.style("display", "inline-block");
          tool.html(`${d.data.name}<br />(${format(d.data.value)})`);
        })
        .on("click", function(d) {
          tool.style("display", "none");
        })
        .on("mouseout", function(d) {
          tool.style("display", "none");
        });
      node
        .append("foreignObject")
        .attr("class", "foreignObject")
        .attr("width", function(d) {
          return d.dx - paddingAllowance;
        })
        .attr("height", function(d) {
          return d.dy - paddingAllowance;
        })
        .append("xhtml:body")
        .attr("class", "labelbody")
        .append("div")
        .attr("class", "label")
        .text(function(d) {
          return d.name;
        })
        .attr("text-anchor", "middle");
      node
        .append("clipPath")
        .attr("id", d => (d.clipUid = "clip"))
        .append("use")
        .attr("xlink:href", d => d.leafUid.href);

      node
        .append("text")
        .attr("clip-path", d => d.clipUid)
        .attr("font-weight", d => (d === root ? "bold" : null))
        .attr("font-size", d => {
          if (d === root) return "0.8em";
          const width = x(d.x1) - x(d.x0),
            height = y(d.y1) - y(d.y0);
          return Math.max(
            Math.min(
              width / 5,
              height / 2,
              Math.sqrt(width * width + height * height) / 25
            ),
            9
          );
        })
        .attr("text-anchor", d => (d === root ? null : "middle"))
        .attr("transform", d =>
          d === root
            ? null
            : `translate(${(x(d.x1) - x(d.x0)) / 2}, ${(y(d.y1) - y(d.y0)) /
                2})`
        )
        .selectAll("tspan")
        .data(d =>
          d === root
            ? name(d).split(/(?=\/)/g)
            : checkLowVal(d)
            ? d.data.name.split(/(\s+)/).concat(format(d.data.value))
            : d.data.name.split(/(\s+)/).concat(format(d.data.value))
        )
        .join("tspan")
        .attr("x", 3)
        .attr(
          "y",
          (d, i, nodes) =>
            `${(i === nodes.length - 1) * 0.3 + (i - nodes.length / 2) * 0.9}em`
        )
        .text(d => d);
      node
        .selectAll("text")
        .classed("text-title", d => d === root)
        .classed("text-tile", d => d !== root)
        .filter(d => d === root)
        .selectAll("tspan")
        .attr("y", "1.1em")
        .attr("x", undefined);
      group.call(position, root);
    }
    function position(group, root) {
      group
        .selectAll("g")
        .attr("transform", d =>
          d === root ? `translate(0,-30)` : `translate(${x(d.x0)},${y(d.y0)})`
        )
        .select("rect")
        .attr("width", d => (d === root ? width : x(d.x1) - x(d.x0)))
        .attr("height", d => (d === root ? 30 : y(d.y1) - y(d.y0)));
    }

    // When zooming in, draw the new nodes on top, and fade them in.
    function zoomin(d) {
      console.log("The zoomin func", d.data);
      x.domain([d.x0, d.x1]);
      y.domain([d.y0, d.y1]);
      const group0 = group.attr("pointer-events", "none");
      const group1 = (group = svg.append("g").call(render, d));
      svg
        .transition()
        .duration(750)
        .call(t =>
          group0
            .transition(t)
            .remove()
            .call(position, d.parent)
        )
        .call(t =>
          group1
            .transition(t)
            .attrTween("opacity", () => d3.interpolate(0, 1))
            .call(position, d)
        );
    }

    // When zooming out, draw the old nodes on top, and fade them out.
    function zoomout(d) {
      console.log("The zoomout func", d.parent.data);
      x.domain([d.parent.x0, d.parent.x1]);
      y.domain([d.parent.y0, d.parent.y1]);
      const group0 = group.attr("pointer-events", "none");
      const group1 = (group = svg.insert("g", "*").call(render, d.parent));
      svg
        .transition()
        .duration(750)
        .call(t =>
          group0
            .transition(t)
            .remove()
            .attrTween("opacity", () => d3.interpolate(1, 0))
            .call(position, d)
        )
        .call(t => group1.transition(t).call(position, d.parent));
    }

    return svg.node();
  };
  componentDidMount() {
    this.createTreeChart();
  }
  render() {
    return (
      <React.Fragment>
        <div id="chart" />
      </React.Fragment>
    );
  }
}
classtreegraph扩展了React.Component{
createTreeChart=()=>{
常数宽度=550;
常数高度=500;
var paddingAllowance=2;
常量格式=d3.格式(“,d”);
常量checkLowVal=d=>{
console.log(“ChecklowVal”,d);
如果(d.值<2){
返回true;
}
};
const name=d=>
D
.祖先()
.reverse()
.map(d=>d.data.name)
.加入(“/”);
功能块(节点x0、y0、x1、y1){
d3.树状结构(节点,0,0,宽度,高度);
for(node.children的常量子节点){
child.x0=x0+(child.x0/宽度)*(x1-x0);
child.x1=x0+(child.x1/宽度)*(x1-x0);
child.y0=y0+(child.y0/身高)*(y1-y0);
child.y1=y0+(child.y1/身高)*(y1-y0);
}
}
常量树映射=数据=>
d3.treemap().tile(tile)(
d3
.层次结构(数据)
.sum(d=>d.value)
.sort((a,b)=>b.value-a.value)
);
常量svg=d3
.选择(“图表”)
.append(“svg”)
.attr(“视图框”[0.5,-30.5,宽度,高度+30])
.style(“字体”,“16px无衬线”);
常量x=d3.scaleLinear().rangeRound([0,宽度]);
常量y=d3.scaleLinear().rangeRound([0,高度]);
让group=svg.append(“g”).call(render,treemap(data));
函数呈现(组、根){
常量节点=组
.全选(“g”)
.data(root.children.concat(root))
.加入(“g”);
节点
.filter(d=>(d==root?d.parent:d.children))
.attr(“光标”、“指针”)
.on(“单击”,d=>(d==root?zoomout(root):zoomin(d));
变量工具=d3
.选择(“正文”)
.附加(“div”)
.attr(“类”、“工具提示”);
d3.选择(window.frameElement).style(“height”,height-20+“px”);
d3.选择(window.frameElement).style(“宽度”,宽度-20+“px”);
节点
.append(“rect”)
.attr(“id”,d=>(d.leafUid=“leaf”))
.attr(“填充”,d=>
d===根?#fff:d.儿童?#045c79:“#045c79”
)
.attr(“笔划”、“fff”)
.on(“mousemove”,函数(d){
工具样式(“左”,d3.event.pageX+10+“px”);
工具样式(“top”,d3.event.pageY-20+“px”);
工具样式(“显示”、“内联块”);
html(`${d.data.name}
(${format(d.data.value)})`); }) .打开(“单击”,功能(d){ 工具样式(“显示”、“无”); }) .开启(“鼠标出”,功能(d){ 工具样式(“显示”、“无”); }); 节点 .append(“外来对象”) .attr(“类”、“外来对象”) .attr(“宽度”,函数(d){ 返回d.dx-填充允许值; }) .attr(“高度”,功能(d){ 返回d.dy-填充允许值; }) .append(“xhtml:body”) .attr(“类”、“标签体”) .附加(“div”) .attr(“类别”、“标签”) .文本(功能(d){ 返回d.name; }) .attr(“文本锚定”、“中间”); 节点 .append(“clipPath”) .attr(“id”,d=>(d.clipUid=“clip”)) .append(“使用”) .attr(“xlink:href”,d=>d.leafUid.href); 节点 .append(“文本”) .attr(“剪辑路径”,d=>d.clipUid) .attr(“字体重量”,d=>(d==根?“粗体”:null)) .attr(“字体大小”,d=>{ 如果(d==根)返回“0.8em”; 常数宽度=x(d.x1)-x(d.x0), 高度=y(d.y1)-y(d.y0); 返回Math.max( Math.min( 宽度/5, 高度/2, 数学sqrt(宽*宽+高*高)/25 ), 9 ); }) .attr(“文本锚定”,d=>(d==根?null:“中间”)) .attr(“转换”,d=> d==根 无效的 :`translate(${(x(d.x1)-x(d.x0))/2},${(y(d.y1)-y(d.y0))/ 2})` ) .selectAll(“tspan”) .数据(d=> d==根 名称(d).拆分(/(?=\/)/g) :checkLowVal(d) ?d.data.name.split(/(\s+/).concat(格式(d.data.value)) :d.data.name.split(/(\s+/).concat(格式(d.data.value)) ) .加入(“tspan”) .attr(“x”,3) 艾特先生( “y”, (d,i,节点)=> `${(i==nodes.length-1)*0.3+(i-nodes.length/2)*0.9}em` ) .text(d=>d); 节点 .selectAll(“文本”) .classed(“文本标题”,d=>d==root) .classed(“文本平铺”,d=>d!==root) .filter(d=>d==root) .selectAll(“tspan”) .attr(“y”,“1.1米”) .attr(“x”,未定义); 组调用(位置、根); } 功能位置(组、根){ 组 .全选(“g”) .attr(“转换”,d=> d==root?`translate(0,-30)`:`translate(${x(d.x0)},${y(d.y0)})` ) .选择(“rect”) .attr(“宽度”,d=>(d==根?宽度:x(d.x1)-x(d.x0))) .attr(“高度”,d=>(d==根?30:y(d.y1)-y(d.y0)); } //放大时,在顶部绘制新节点,然后淡入淡入。 函数缩放(d){ log(“缩放函数”,d.data); x、 域([d.x0,d.x1]); y、 域([d.y0,d.y1]); constgroup0=group.attr(“指针事件”,“无”); constgroup1=(group=svg.append(“g”).call(render,d)); svg .transition() .持续时间(750) .call(t=> 第0组 .过渡(t)