javascript - 在 D3 Hierarchy Typescript 中,每个父子对具有相同的颜色

标签 javascript typescript d3.js parent-child force-layout

我正在尝试使用 here 中的“D3 可折叠力布局”的一个很好的示例。 。我已将输入数据修改如下

 const data = {
 "name": "directory",
 "children": [
  {"name": "1st file", 
    "children": [{"name": "1f 1st function", "group": 1},  
    {"name": "1f 2nd function", "group": 1},
    {"name": "1f 3rd function", "group": 1},
    {"name": "1f 4th function", "group": 1}], "group": 1,},
  {"name": "2nd file", "children": [
    {"name": "2f 1st function", "group": 2},
    {"name": "2f 2nd function", "group": 2}], "group": 2},
  {"name": "3rd file", "children": [
    {"name": "3f 1st function", "group": 3}
  ], "group": 3},
  {"name": "4th file", "children": [
    {"name": "4f 1st function", "group": 4},
    {"name": "4f 2nd function", "group": 4},
    {"name": "4f 3rd function", "group": 4}
  ], "group": 4}
 ],
 "group": 0
}

我希望根据组值使所有父子节点具有相同的颜色。 例如:所有“group:1”将具有红色,“group:2”将具有绿色等。谁能帮我解决这个问题吗?感谢您抽出时间。

最佳答案

您所需要的只是一个序数尺度。例如:

const colorScale = d3.scaleOrdinal()
  .domain(d3.range(5))
  .range(d3.schemeDark2);

这里我使用了一个名为d3.schemeDark2的颜色数组,根据你想要的颜色进行更改。对于域,由于您的是数字,因此我使用d3.range

然后,绘制圆圈:

.style('fill', function(d){
    return colorScale(d.data.group)
})

以下是包含您的数据和这些更改的代码:

const data = {
  "name": "directory",
  "children": [{
      "name": "1st file",
      "children": [{
          "name": "1f 1st function",
          "group": 1
        },
        {
          "name": "1f 2nd function",
          "group": 1
        },
        {
          "name": "1f 3rd function",
          "group": 1
        },
        {
          "name": "1f 4th function",
          "group": 1
        }
      ],
      "group": 1,
    },
    {
      "name": "2nd file",
      "children": [{
          "name": "2f 1st function",
          "group": 2
        },
        {
          "name": "2f 2nd function",
          "group": 2
        }
      ],
      "group": 2
    },
    {
      "name": "3rd file",
      "children": [{
        "name": "3f 1st function",
        "group": 3
      }],
      "group": 3
    },
    {
      "name": "4th file",
      "children": [{
          "name": "4f 1st function",
          "group": 4
        },
        {
          "name": "4f 2nd function",
          "group": 4
        },
        {
          "name": "4f 3rd function",
          "group": 4
        }
      ],
      "group": 4
    }
  ],
  "group": 0
};

const colorScale = d3.scaleOrdinal()
  .domain(d3.range(5))
  .range(d3.schemeDark2);

const width = 500,
  height = 400;

let i = 0;

const root = d3.hierarchy(data);
const transform = d3.zoomIdentity;
let node, link;

const svg = d3.select('body').append('svg')
  .call(d3.zoom().scaleExtent([1 / 2, 8]).on('zoom', zoomed))
  .append('g')
  .attr('transform', 'translate(40,0)');



const simulation = d3.forceSimulation()
  .force('link', d3.forceLink().id(function(d) {
    return d.id;
  }))
  .force('charge', d3.forceManyBody().strength(-15).distanceMax(300))
  .force('center', d3.forceCenter(width / 2, height / 4))
  .on('tick', ticked)


function update() {
  const nodes = flatten(root)
  const links = root.links()

  link = svg
    .selectAll('.link')
    .data(links, function(d) {
      return d.target.id
    })

  link.exit().remove()

  const linkEnter = link
    .enter()
    .append('line')
    .attr('class', 'link')
    .style('stroke', '#000')
    .style('opacity', '0.2')
    .style('stroke-width', 2)

  link = linkEnter.merge(link)

  node = svg
    .selectAll('.node')
    .data(nodes, function(d) {
      return d.id
    })

  node.exit().remove()

  const nodeEnter = node
    .enter()
    .append('g')
    .attr('class', 'node')
    .attr('stroke', '#666')
    .attr('stroke-width', 2)
    .style('fill', function(d) {
      return colorScale(d.data.group)
    })
    .style('opacity', 1)
    .on('click', clicked)
    .call(d3.drag()
      .on('start', dragstarted)
      .on('drag', dragged)
      .on('end', dragended))

  nodeEnter.append('circle')
    .attr("r", function(d) {
      return Math.sqrt(d.data.size) / 10 || 4.5;
    })
    .style('text-anchor', function(d) {
      return d.children ? 'end' : 'start';
    })
    .text(function(d) {
      return d.data.name
    })

  node = nodeEnter.merge(node)
  simulation.nodes(nodes)
  simulation.force('link').links(links)
}

function sizeContain(num) {
  num = num > 1000 ? num / 1000 : num / 100
  if (num < 4) num = 4
  return num
}

function color(d) {
  return d._children ? "#51A1DC" // collapsed package
    :
    d.children ? "#51A1DC" // expanded package
    :
    "#F94B4C"; // leaf node
}

function radius(d) {
  return d._children ? 8 :
    d.children ? 8 :
    4
}

function ticked() {
  link
    .attr('x1', function(d) {
      return d.source.x;
    })
    .attr('y1', function(d) {
      return d.source.y;
    })
    .attr('x2', function(d) {
      return d.target.x;
    })
    .attr('y2', function(d) {
      return d.target.y;
    })

  node
    .attr('transform', function(d) {
      return `translate(${d.x}, ${d.y})`
    })
}

function clicked(d) {
  if (!d3.event.defaultPrevented) {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
    update()
  }
}


function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart()
  d.fx = d.x
  d.fy = d.y
}

function dragged(d) {
  d.fx = d3.event.x
  d.fy = d3.event.y
}

function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(0)
  d.fx = null
  d.fy = null
}

function flatten(root) {
  const nodes = []

  function recurse(node) {
    if (node.children) node.children.forEach(recurse)
    if (!node.id) node.id = ++i;
    else ++i;
    nodes.push(node)
  }
  recurse(root)
  return nodes
}

function zoomed() {
  svg.attr('transform', d3.event.transform)
}

update()
body {
  background-color: #E6E6E6;
}

svg {
  width: 100vw;
  height: 100vh;
}

.node {
  pointer-events: all;
  cursor: pointer;
  z-index: 1000;
}

.node text {
  font: 8px sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

关于javascript - 在 D3 Hierarchy Typescript 中,每个父子对具有相同的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58870081/

相关文章:

typescript - 使用 Typescript 在 Vue 数据对象中设置数据类型

typescript - 有什么理由将实现接口(interface)放到类中吗?

javascript - d3时间刻度在时间范围之前和之后添加时间间隔的百分比

javascript - D3.js 中带有标记的过渡路径长度使标记消失

javascript - 如何使用 MSSQL 查询结果作为我的选择框选项

javascript - 如何在我的 aspx 页面上显示变量值后面的代码

javascript - 从数组中删除特定项目

javascript - 无法附加到 jQuery 换行

css - 将自定义类动态添加到 dc.selectMenu; IE11删除它

javascript - 如何在 Angular2 中导入 d3pie.js TypeScript 定义