Nano Hash - криптовалюты, майнинг, программирование

Общий шаблон обновления с d3 для гистограмм с прямоугольниками

Я сталкиваюсь с этой проблемой, когда пытаюсь получить гистограмму с элементами, разделенными и видимыми для конкретного бина. Но когда данные изменяются, все идет в enter() и ничего не происходит в обновлении, кажется. Таким образом, все существующие элементы также переходят и появляются сверху, а не просто меняют свои значения. Пожалуйста, взгляните на код, который я приложил ниже, который выводит изображение в виде прикрепленного изображения. Не могу понять, почему обновление не работает, только войти туда. Я не могу поделиться всем кодом, но это основная проблема.введите здесь описание изображения

Структура HTML — введите здесь описание изображения

let initialRender = true;
let selectedData1 = true;
const margin = {
    top: 10,
    right: 30,
    bottom: 30,
    left: 30
  },
  width = 550 - margin.left - margin.right,
  height = 150 - margin.top - margin.bottom;

function printChart(asd, data, dataGradients) {
  const svg = d3.select('#data-viz')
  // const isZoomed = map.getZoom() > zoomThreshold;

  // if (isZoomed !== changedZoom) {
  //   initialRender = true;
  //   changedZoom = isZoomed;
  // }

  // X axis and scale ------------->>>>>>>>>>>>>>>>>>>>
  const xScale = d3.scaleLinear()
    .domain(d3.extent(data.map(d => d.value)))
    .range([0, width])

  const xAxisCall = d3.axisBottom(xScale)
    .tickFormat(d3.format(".2s"))
    .ticks(5)
    .tickSizeOuter(0);

  let xAxis = null
  if (initialRender) {
    d3.select(".axis-x").remove()
    xAxis = svg.append("g")
      .attr("class", "axis-x")
      .attr("transform", "translate(0," + 115 + ")")
    initialRender = false
  } else {
    xAxis = d3.select(".axis-x")
  }

  xAxis.transition()
    .duration(2000)
    .ease(d3.easeSinInOut)
    .call(xAxisCall)
  // X axis and scale <<<<<<<<<<<<<<<<-----------------------------
  const binMin = 5;
  const binMax = 150;
  const tDuration = 3000;

  // Just to calculate max elements in each bin ---------->>>>>>>>>>>>>>>>>>
  let histogram = d3.histogram()
    .value(d => d.value)
    .domain(xScale.domain())
    .thresholds(xScale.ticks(10));

  let bins = histogram(data).filter(d => d.length > 0);
  console.log(bins);
  const max = d3.max(bins.map(bin => bin.length))
  const maxBinSize = max <= 10 ? 10 : max
  // Just to calculate max elements in each bin <<<<<<<<<<<<----------------

  // Decide parameters for histogram ------------>>>>>>>>>>>>>>>>>
  const dotSizeScale = d3.scaleLinear()
    .domain([binMin, binMax])
    .range([10, 4])
  const dotSize = dotSizeScale(maxBinSize);

  const dotSpacingScale = d3.scaleLinear()
    .domain([binMin, binMax])
    .range([12, 6])
  const dotSpacing = dotSpacingScale(maxBinSize);

  const thresholdScale = d3.scaleLinear()
    .domain([binMin, binMax])
    .range([10, 100])
  const threshold = thresholdScale(maxBinSize);

  const yTransformMarginScale = d3.scaleLinear()
    .domain([binMin, binMax])
    .range([100, 100])
  const yTransformMargin = yTransformMarginScale(maxBinSize);

  if (dotSize !== 10) {
    d3.selectAll('.gBin').remove()
    d3.selectAll('rect').remove()
  }

  histogram = d3.histogram()
    .value(d => d.value)
    .domain(xScale.domain())
    .thresholds(xScale.ticks(threshold));

  bins = histogram(data).filter(d => d.length > 0);
  // Decide parameters for histogram <<<<<<<<<<<<<<<<<<<<--------------------------

  // Y axis scale -------------------->>>>>>>>>>>>>>>>>>>>
  var yScale = d3.scaleLinear()
    .range([height, 0]);

  yScale.domain([0, d3.max(bins, (d) => d.length)]);
  svg.append("g")
    .attr("class", "axis-y")
    .call(d3.axisLeft(yScale));
  d3.select(".axis-y")
    .remove()
  // Y axis scale <<<<<<<<<<<<<<<<<<<<<<<-----------------

  const binGroup = svg.selectAll(".gBin")
    .data(bins,
      (d) => {
        console.log('id 1', d.x0)
        return d.x0
      }
    )

  binGroup
    .exit()
    .transition()
    .duration(2000)
    .style("opacity", 0)
    .remove()

  const binGroupEnter = binGroup
    .enter()
    .append("g")
    .merge(binGroup)
    .attr("class", "gBin")
    .attr("x", 1)
    .attr("transform", function(d) {
      return "translate(" + xScale(d.x0) + "," + yTransformMargin + ")";
    })
    .attr("width", 10)

  const elements = binGroupEnter.selectAll("rect")
    .data(d => d.map((p, i) => ({
        id: p.id,
        idx: i,
        value: p.value,
      })),
      function(d) {
        console.log('id 2', d)
        return d.id
      }
    )

  elements.exit()
    .transition()
    .duration(tDuration)
    .style("opacity", 0)
    .remove()

  elements
    .enter()
    .append("rect")
    .merge(elements)
    .attr("y", -(height + margin.top))
    // .on("mouseover", tooltipOn)
    // .on("mouseout", tooltipOff)
    .transition()
    .delay(function(d, i) {
      return 50 * i;
    })
    .duration(tDuration)
    .attr("id", d => d.value)
    .attr("y", (d, i) => -(i * dotSpacing))
    .attr("width", dotSize)
    .attr("height", dotSize)
    // .style("fill", (d) => getBinColor(d.value, dataGradients))
    .style("fill", 'red')
}

const data1 = [{
  id: 1,
  value: 14
}, {
  id: 13,
  value: 12
}, {
  id: 2,
  value: 50
}, {
  id: 32,
  value: 142
}]
const data2 = [{
  id: 1,
  value: 135
}, {
  id: 7,
  value: 2
}, {
  id: 2,
  value: 50
}, {
  id: 32,
  value: 50
}]
printChart(null, data1, null)

function changeData() {
  selectedData1 ?
    printChart(null, data2, null) :
    printChart(null, data1, null)
  selectedData1 = !selectedData1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg width="550" height="250" id="data-viz">
      <g transform="translate(30, 100)">
      </g>
    </svg>
<button onclick="changeData()"> Update data </button>


  • Вы снова вызываете весь этот блок кода при обновлении гистограммы? Конечно, было бы полезно, если бы вы добавили полностью воспроизводимый пример, а не просто симпатично и вставили его из своего кода. 20.12.2020
  • @Mark Я хотел бы поделиться закрытыми ключами для карты и т. д., поэтому я не делюсь кодом. Хотя могу рассказать подробности. Я пытаюсь добиться чего-то вроде opportunityatlas.org. Здесь, если вы продолжите и посмотрите в верхний правый угол и измените карту, элементы имеют плавный переход. Пытаюсь повторить то же самое. Вы можете выбрать один из элементов и просмотреть его. Структура, которую я делаю, похожа на приведенный выше код. 21.12.2020
  • @Mark Есть ячейки g элементов с классом .gBin, и в этих ячейках есть прямоугольники для каждого элемента. Я также предоставил уникальный ключ со вторым методом обратного вызова привязки данных. x0 для каждого бина и фактический идентификатор из данных для каждого прямоугольника в бине. Пожалуйста, помогите мне за то же самое. Каждый раз, когда график входит в режим ввода и никогда не обновляется. Я прикрепил снимок структуры HTML к вопросу для справки. 21.12.2020
  • В этом примере opportunityatlas.org. В правом верхнем углу нажмите «Показать распределение» и выберите «На экране», затем измените карту на экране, это изменит график, но уже присутствующие элементы изменят положение, а другие элементы появятся сверху как часть перехода ввода, но в моем случае все введено и ничего не происходит. Обновить. Я не знаю, правильно ли я реализовал. 21.12.2020
  • @Mark Я также изменил фрагмент кода. Пожалуйста, посмотрите. Идентификаторы данных одинаковы, но все они входят в фазу ввода(). 21.12.2020
  • Обновленный вопрос с правильным кодом - stackoverflow.com/questions/65393713/ 21.12.2020

Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..