Tree.prototype.treeUpdate = function()

in dolphinscheduler-ui/src/views/projects/workflow/definition/tree/use-d3-tree/tree.ts [160:338]


Tree.prototype.treeUpdate = function (source) {
  const tasksStateObj = this.tasksStateObj

  const tasksType = {}

  this.taskTypeNodeOptions.map((v) => {
    tasksType[v.taskType] = {
      color: v.color
    }
  })

  return new Promise((resolve) => {
    const tasks = this.tasks
    const height = Math.max(
      500,
      tasks.length * this.config.barHeight +
        this.config.margin.top +
        this.config.margin.bottom
    )

    d3.select('.tree-svg')
      .transition()
      .duration(this.duration)
      .attr('height', height)

    tasks.forEach((n, i) => {
      n.x = i * this.config.barHeight
    })

    const task = this.svg.selectAll('g.node').data(tasks, (d) => {
      return d.id || (d.id = ++this.i)
    })

    const nodeEnter = task
      .enter()
      .append('g')
      .attr('class', this.nodesClass)
      .attr('transform', () => 'translate(' + source.y0 + ',' + source.x0 + ')')
      .style('opacity', 1e-6)

    // Node circle
    nodeEnter
      .append('circle')
      .attr('r', this.config.barHeight / 3)
      .attr('class', 'task')
      .attr('title', (d) => {
        return d.data.type ? d.data.type : ''
      })
      .attr('height', this.config.barHeight)
      .attr('width', (d) => this.config.barWidth - d.y)
      .style('fill', (d) =>
        d.data.type ? tasksType[d.data.type]?.color : '#fff'
      )
      .attr('task_id', (d) => {
        return d.data.uuid
      })
      .on('click', this.treeToggles)
      .on('mouseover', (e, d) => {
        self.treeTooltip(d.data.type, e)
      })
      .on('mouseout', () => {
        self.removeTooltip()
      })

    // Node text
    nodeEnter
      .append('text')
      .attr('dy', 3.5)
      .attr('dx', this.config.barHeight / 2)
      .text((d) => {
        return d.data.name
      })
      .style('fill', 'var(--n-title-text-color)')

    const translateRatio =
      this.config.nodesMax > 10 ? (this.config.nodesMax > 20 ? 10 : 30) : 60

    // Right node information
    nodeEnter
      .append('g')
      .attr('class', 'stateboxes')
      .attr(
        'transform',
        (d) =>
          'translate(' + (this.config.nodesMax * translateRatio - d.y) + ',0)'
      )
      .selectAll('rect')
      .data((d) => d.data.instances)
      .enter()
      .append('rect')
      .on('click', () => {
        this.removeTooltip()
      })
      .attr('class', 'state')
      .style(
        'fill',
        (d) => (d.state && tasksStateObj[d.state].color) || '#ffffff'
      )
      .attr('rx', (d) => (d.type ? 0 : 12))
      .attr('ry', (d) => (d.type ? 0 : 12))
      .style('shape-rendering', (d) => (d.type ? 'crispEdges' : 'auto'))
      .attr(
        'x',
        (d, i) => i * (this.config.squareSize + this.config.squarePading)
      )
      .attr('y', -(this.config.squareSize / 2))
      .attr('width', 10)
      .attr('height', 10)
      .on('mouseover', (e, d) => {
        self.treeTooltip(rtInstancesTooltip(d, tasksStateObj), e)
      })
      .on('mouseout', () => {
        self.removeTooltip()
      })

    // Convert nodes to their new location。
    nodeEnter
      .transition()
      .duration(this.duration)
      .attr('transform', (d) => 'translate(' + d.y + ',' + d.x + ')')
      .style('opacity', 1)

    // Node line
    task
      .transition()
      .duration(this.duration)
      .attr('class', this.nodesClass)
      .attr('transform', (d) => 'translate(' + d.y + ',' + d.x + ')')
      .style('opacity', 1)

    // Convert the exit node to the new location of the parent node。
    task
      .exit()
      .transition()
      .duration(this.duration)
      .attr('transform', () => 'translate(' + source.y + ',' + source.x + ')')
      .style('opacity', 1e-6)
      .remove()

    // Update link
    const link = this.svg
      .selectAll('path.link')
      .data(this.links, (d) => d.target.id)

    // Enter any new links in the previous location of the parent node。
    link
      .enter()
      .insert('path', 'g')
      .attr('class', 'link')
      .attr('d', () => {
        const o = { x: source.x0, y: source.y0 }
        return this.diagonal({ source: o, target: o })
      })
      .transition()
      .duration(this.duration)
      .attr('d', this.diagonal)

    // Transition link
    link.transition().duration(this.duration).attr('d', this.diagonal)

    // Convert the exit node to the new location of the parent node
    link
      .exit()
      .transition()
      .duration(this.duration)
      .attr('d', () => {
        const o = { x: source.x, y: source.y }
        return this.diagonal({ source: o, target: o })
      })
      .remove()

    // Hide the old position for a transition.
    tasks.forEach((d) => {
      d.x0 = d.x
      d.y0 = d.y
    })
    resolve()
  })
}