React+D3組件開發之treemap(樹圖)

背景

在React前端項目中使用D3JS定製可視化組件,treemap支持節點的新建、刪除、縮放、全屏等功能

技術實現

首先圖表線和點的數據

	  // dataSource初始數據
	  const hierarchyData = d3.hierarchy(dataSource)
      // hierarchy layout and add node.x,node.y
      const treeNode = this.tree(hierarchyData);
      nodes = treeNode.descendants();
      links = treeNode.links();
      nodes = nodes.map(node => {
        if (node.active) {
          node.active = false;
          if (node.parent) {
            node.parent.active = false;
          }
        }
        if (node.data.name === currentNode.name) {
          node.active = true;
          if (node.parent) {
            node.parent.active = true;
          }
        }
        return node;
      });

畫線path

<g>
  {
    links.map((link, i) => {
    const start = { x: link.source.x, y: link.source.y + CONSTANT.STARTBUF };
    const end = { x: link.target.x, y: link.target.y + CONSTANT.ENDBUF };
    const pathLink = this.bezierCurveGenerator({ source: start, target: end });

    return <path 
      key={i}
      d={pathLink}
      fill='none'
      stroke={CONSTANT.THEME.LINESTROKE}
      strokeWidth='1'
      strokeDasharray={CONSTANT.THEME.DASHARRAY}
      markerEnd='url(#arrow)'/>
  })}
</g>

畫節點

<g>
  {nodes.map((node, i) => {
    node.type = node.data.type;
    node.tmp = node.data.tmp;
    node.error = node.data.error;
    node.avgTime = node.data.avgTime;
    node.name = node.data.name;

    return (<g key={i} transform={`translate(${node.y}, ${node.x - 10})`}>
      <defs>
        <marker id="arrow"
          markerUnits="strokeWidth"
          markerWidth={CONSTANT.MARKER.MARKERWIDTH}
          markerHeight={CONSTANT.MARKER.MARKERHIEGHT}
          viewBox={CONSTANT.MARKER.VIEWBOX} 
          refX={CONSTANT.MARKER.REFX}
          refY={CONSTANT.MARKER.REFY}
          orient={CONSTANT.MARKER.ORIENT}>
          <path d={CONSTANT.MARKER.PATH} fill={CONSTANT.MARKER.FILL} />
        </marker>
      </defs>
      <circle
        cx={CONSTANT.CIRCLE.CX}
        cy={CONSTANT.CIRCLE.CY}
        r={CONSTANT.CIRCLE.R}
        fill='#fff'
        stroke={node.active ? CONSTANT.THEME.ACTIVE : CONSTANT.THEME.NONEACTIVE}
        strokeWidth={node.active ? 2 : 1}
        style={{cursor: 'pointer'}}
        onClick={(event) => this.nodeActive(event, node)} />
      <image
        href={node.depth === 0 ? user : node.depth === 1 ? earth : minusCircle}
        style={{cursor: 'pointer'}} 
        onClick={(event) => this.nodeActive(event, node)}/>
      <rect x='10' y='32' width='40' height='20'
        fill={node.data.type === CONSTANT.PROD ? CONSTANT.THEME.RECTBLUE : CONSTANT.THEME.RECTRED} />
      <text
        x='17' y='46'
        fill={node.data.type === CONSTANT.PROD ? CONSTANT.THEME.TEXTBLACK : CONSTANT.THEME.TEXTWHITE}
        style={{fontSize: CONSTANT.THEME.FONTSIZE}}>
        {node.type}
      </text>
      <text x='5' y='47' fill='#000' textAnchor='end' style={{fontSize: CONSTANT.THEME.FONTSIZE}}>
        {node.name}
      </text>
    </g>)
  })}
</g>

效果展示

treemap

github地址

tree-map-react

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章