react关联线demo

发布于 2021-04-05  766 次阅读


关联线

最近有个需求要做一个关联线的功能,需要这个树结构有增删改查的功能,下面就是最简单的渲染功能,实际整个功能主体代码有两百多行,下面只是开发初期写的一个demo有些地方还不完善

import React, { Component } from 'react'
import { data } from './config'
import './index.scss'

export class FlowChart extends Component {

  getNodes = (data) => {
    return data.map((item, index) => {
      if (!item.children.length) {
        return (
          <div key={index} className={`${ item?.id !== '0' ? 'item-lead' : 'item-root'  }`}>
            <div>{item.value}</div>
          </div>
        );
      } else {
        return (
          <div className='item-box'>
            <div className={`${ item?.id !== '0' ? 'item-lead' : 'item-root'  }`}>{item.value}</div>
            <div key={index} className='item-node' >
              {
                this.getNodes(item.children)
              }
            </div>
          </div>
        );
      }
    });
  };

  render() {
    return (
      <div className='main'>
        {
          this.getNodes(data)
        }
      </div>
    )
  }
}

export default FlowChart
$lineWidth: 30px; //横线的宽度

.main {
  border: 1px solid #E4E7ED;
  padding: 10px;
}
.item-box {
  display: flex;
  align-items: center;
}
.item-root {
  padding: 10px $lineWidth;
}
.item-lead {
  padding: 10px $lineWidth;
  position: relative;
  &::before{
    content: '';
    position: absolute;
    background:#E4E7ED;
    top:50%;
    left: 0;
    height:1px;
    width:$lineWidth;
  }
}
.item-node {
  position: relative;
  display: flex;
  flex-direction: column;
  > div {
    flex: 1;
  }
  &::before{
    content: '';
    position: absolute;
    background:#E4E7ED;
    top:50%;
    left:-$lineWidth;
    height:1px;
    width:$lineWidth;
  }
  > div {
    position: relative;
    &:first-child::after{
      content: '';
      position: absolute;
      background:#E4E7ED;
      top: 50%;
      width:1px;
      height:50%;
      left: 0;
    }
    &:last-child::after{
      content: '';
      position: absolute;
      background:#E4E7ED;
      bottom: 50%;
      width:1px;
      height:50%;
      left: 0;
    }
    &:not(:first-child):not(:last-child)::after {
      content: '';
      position: absolute;
      background:#E4E7ED;
      width:1px;
      height:100%;
      left: 0;
      top: 0;
    }
  }
}
export const data = [{
  value: '根',
  type: 'relation',
  id: '0',
  children: [
    {
      value: '第一层-01',
      type: 'condition',
      children: [
        {
          value: '第二层-01-01',
          type: 'condition',
          children: []
        },
        {
          value: '第二层-01-02',
          type: 'relation',
          children: [
            {
              value: '第二层-01-02-01',
              type: 'relation',
              children: []
            },
            {
              value: '第二层-01-02-01',
              type: 'condition',
              children: []
            },
            {
              value: '第二层-01-02-02',
              type: 'condition',
              children: []
            },
            {
              value: '第二层-01-02-01',
              type: 'condition',
              children: []
            },
            {
              value: '第二层-01-02-02',
              type: 'relation',
              children: []
            }
          ]
        },
        {
          value: '第二层-01-03',
          type: 'relation',
          children: []
        },
        {
          value: '第二层-01-01',
          type: 'condition',
          children: []
        },
        {
          value: '第二层-01-02-01',
          type: 'relation',
          children: []
        },
        {
          value: '第二层-01-02-02',
          type: 'condition',
          children: []
        }
      ]
    },
    {
      value: '第一层-02',
      type: 'relation',
      children: []
    },
    {
      value: '第二层-01-02-01',
      type: 'condition',
      children: []
    },
    {
      value: '第二层-01-02-02',
      type: 'relation',
      children: []
    }
  ]
}]

I struggle for what I love, so I can be happy here.