d3 дублировать график при обновлении данных - PullRequest
1 голос
/ 26 мая 2020

Я хотел обновить график d3, когда пользователь выбирает сайт. Но когда я выбираю раскрывающееся меню вверху, у меня создается новый график, и я не могу найти способ его удалить.

enter image description here

this это код в <script>

<script>

import * as d3 from 'd3'
import { rgbaToHex } from '../utils/color.ts'

export default {
  data () {
    return {
      selectedSite: '',
      selectedWhale: '',
      groupType: '',
      heatmapShow: false
    }
  },
  mounted () {
    this.generateChart()
  },
  methods: {
    generateChart () {
      // set the dimensions and margins of the graph
      const margin = { top: 20, right: 20, bottom: 30, left: 30 }
      const width = 1850 - margin.left - margin.right
      const height = 200 - margin.top - margin.bottom

      // make the area for the graph to stay
      const svg = d3.select('#heatmap')
        .append('svg') // svg area can include headers and color scales
        .attr('width', width + margin.left + margin.right) // set width
        .attr('height', height + margin.top + margin.bottom) // set height
        .append('g') // new g tag area for graph only
        .attr('transform', `translate(${margin.left}, ${margin.bottom})`)
        // stick g tag to the bottom
      const xLabel = d3.range(259)
      const yLabel = d3.range(23, -1, -1)

      const x = d3.scaleBand()
        .domain(xLabel)
        .range([0, width])
        .padding(0.05)

      svg.append('g')
        .attr('transform', `translate(0, ${height})`)
        .call(d3.axisBottom(x).tickValues(x.domain().filter((_, i) => !(i % 6))))

      const y = d3.scaleBand()
        .domain(yLabel)
        .range([height, 0])
        .padding(0.05)

      svg.append('g').call(d3.axisLeft(y).tickValues(y.domain().filter((_, i) => !(i % 5))))

      d3.json('../predictions.json').then((data) => {
        const u = svg.selectAll().data(data.heatmaps[this.selectedWhale][this.selectedSite])

        u.exit().remove()

        const uEnter = u.enter().append('rect')

        uEnter
          .merge(u)
          .transition()
          .duration(1000)
          .attr('x', function (d) {
            return x(d[1]) // return cell's position
          })
          .attr('y', function (d) {
            return y(d[0])
          })
          .attr('cx', 1)
          .attr('cy', 1)
          .attr('width', x.bandwidth()) // return cell's width
          .attr('height', y.bandwidth()) // return cell's height
          .style('fill', function (d) {
            return rgbaToHex(0, 128, 255, 100 * d[2])
          })
          .on('mouseover', function () { // box stroke when hover
            d3.select(this)
              .style('stroke', 'black')
              .style('opacity', 1)
          })
          .on('mouseout', function () { // fade block stroke when mouse leave the cell
            d3.select(this)
              .style('stroke', 'none')
              .style('opacity', 0.8)
          })
          .on('click', (d) => {
            console.log(d)
            this.heatmapShow = true
          })

        uEnter.exit().remove()
      })
    }
  },
  watch: {
    selectedSite: function () {
      this.generateChart()
    },
    selectedWhale: function () {
      this.generateChart()
    },
    groupType: function (value) {
      console.log(value)
    }
  }
}
</script>

Ответы [ 2 ]

0 голосов
/ 26 мая 2020

Итак, что я сделал, чтобы исправить это, как было предложено ранее, просто добавил d3.select('svg').remove(), прежде чем я снова начну создавать svg const.

      const margin = { top: 20, right: 20, bottom: 30, left: 30 }
      const width = 1850 - margin.left - margin.right
      const height = 200 - margin.top - margin.bottom

      d3.select('svg').remove()

      // make the area for the graph to stay
      const svg = d3.select('#heatmap')
        .append('svg') // svg area can include headers and color scales

      /* rest of the code */
0 голосов
/ 26 мая 2020

Похоже, что вы выбираете идентификатор для рисования на нем холста графика, но добавляете его вместо того, чтобы вставлять новый.

selection.append (type)

Если указанный тип является строкой, добавляет новый элемент этого типа (имя тега) в качестве последнего дочернего элемента каждого выбранного элемента или перед следующим следующим родственником в выборе обновления, если это выбор ввода.

Подробнее по теме написано здесь .

Попробуйте удалить идентификатор перед его перекрашиванием с помощью selection remove , а затем попробуйте добавить / вставить снова

...