Добавить не работает при вызове во второй раз

Я делаю функцию js для отображения данных в новом div каждый раз, когда он вызывается, проблема в том, что некоторые добавления не работают для второго вызова, мне нужна ваша помощь, чтобы узнать, что не так.

Снимок экрана, демонстрирующий разницу между результатами первого и второго звонка Добавить не работает при вызове во второй раз

<!DOCTYPE html>
<meta charset = "utf-8">

<head>
  <style>
    .axis {
      font: 10px sans-serif;
    }
    
    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
      shape-rendering: crispEdges;
    }
  </style>
</head>

<body>
  <script src = "http://d3js.org/d3.v3.min.js"></script>
  <script>
    var data = [];
    data.push({
      date: " 2019-03-25 00:00:00 ",
      value: 509
    });
    data.push({
      date: " 2019-03-26 00:00:00 ",
      value: 505
    });
    data.push({
      date: " 2019-03-27 00:00:00 ",
      value: 504
    });
    data.push({
      date: " 2019-03-28 00:00:00 ",
      value: 517
    });
    data.push({
      date: " 2019-03-29 00:00:00 ",
      value: 376
    });
    data.push({
      date: " 2019-03-30 00:00:00 ",
      value: 474
    });
    data.push({
      date: " 2019-03-31 00:00:00 ",
      value: 504
    });
    data.push({
      date: " 2019-04-01 00:00:00 ",
      value: 510
    });
    data.push({
      date: " 2019-04-02 00:00:00 ",
      value: 507
    });
    data.push({
      date: " 2019-04-03 00:00:00 ",
      value: 516
    });
    data.push({
      date: " 2019-04-04 00:00:00 ",
      value: 529
    });
    data.push({
      date: " 2019-04-05 00:00:00 ",
      value: 380
    });
    data.push({
      date: " 2019-04-06 00:00:00 ",
      value: 455
    });
    data.push({
      date: " 2019-04-07 00:00:00 ",
      value: 513
    });

    function plot(arg) {
      var ddd = arg;
      var margin = {
        top: 20,
        right: 20,
        bottom: 70,
        left: 40
      };
      var width = 600 - margin.left - margin.right;
      var height = 300 - margin.top - margin.bottom;
      // Parse the date / time
      var parseDate = d3.time.format(" %Y-%m-%d %H:%M:%S ").parse;
      var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
      var y = d3.scale.linear().range([height, 0]);
      var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format("%d/%m"));
      var yAxis = d3.svg.axis().scale(y).orient("left").ticks(7);
      var div = d3.select("body").append("div");
      var svg = div.append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);
      var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
      ddd.forEach(function(d) {
        d.date = parseDate(d.date);
        d.value = +d.value;
      });
      x.domain(ddd.map(function(d) {
        return d.date;
      }));
      y.domain([0, d3.max(ddd, function(d) {
        return d.value;
      })]);
      g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).selectAll("text").style("text-anchor", "end").attr("dx", "-.8em").attr("dy", "-.55em").attr("transform", "rotate(-90)");
      g.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(0)").attr("y", -13).attr("dy", ".71em").style("text-anchor", "end").text("Count");
      g.selectAll("bar").data(ddd).enter().append("rect").style("fill", "steelblue").attr("x", function(d) {
        return x(d.date);
      }).attr("width", x.rangeBand()).attr("y", function(d) {
        return y(d.value);
      }).attr("height", function(d) {
        return height - y(d.value);
      });;
    }

    plot(data);
    plot(data);
  </script>
</body>

Попробуйте найти минимальный пример, который воспроизводит проблему. Скорее всего, при этом вы сами найдете свою проблему, в противном случае вы, по крайней мере, привлечете больше читателей, чтобы посмотреть на ваш вопрос.

junvar 09.04.2019 16:32

Спасибо за ответ, вы были правы, если бы я попытался упростить код, я бы нашел, что не так.

LAHOUEL Youssouf 09.04.2019 16:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
161
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вашей функции plot() есть side effect — изменяющийся массив входных данных.

Если передать туда копии, то все будет хорошо:

    plot(data.map(a => Object.assign({}, a)));
    plot(data.map(a => Object.assign({}, a)));

<!DOCTYPE html>
<meta charset = "utf-8">

<head>
  <style>
    .axis {
      font: 10px sans-serif;
    }
    
    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
      shape-rendering: crispEdges;
    }
  </style>
</head>

<body>
  <script src = "http://d3js.org/d3.v3.min.js"></script>
  <script>
    var data = [];
    data.push({
      date: " 2019-03-25 00:00:00 ",
      value: 509
    });
    data.push({
      date: " 2019-03-26 00:00:00 ",
      value: 505
    });
    data.push({
      date: " 2019-03-27 00:00:00 ",
      value: 504
    });
    data.push({
      date: " 2019-03-28 00:00:00 ",
      value: 517
    });
    data.push({
      date: " 2019-03-29 00:00:00 ",
      value: 376
    });
    data.push({
      date: " 2019-03-30 00:00:00 ",
      value: 474
    });
    data.push({
      date: " 2019-03-31 00:00:00 ",
      value: 504
    });
    data.push({
      date: " 2019-04-01 00:00:00 ",
      value: 510
    });
    data.push({
      date: " 2019-04-02 00:00:00 ",
      value: 507
    });
    data.push({
      date: " 2019-04-03 00:00:00 ",
      value: 516
    });
    data.push({
      date: " 2019-04-04 00:00:00 ",
      value: 529
    });
    data.push({
      date: " 2019-04-05 00:00:00 ",
      value: 380
    });
    data.push({
      date: " 2019-04-06 00:00:00 ",
      value: 455
    });
    data.push({
      date: " 2019-04-07 00:00:00 ",
      value: 513
    });

    function plot(arg) {
      var ddd = arg;
      var margin = {
        top: 20,
        right: 20,
        bottom: 70,
        left: 40
      };
      var width = 600 - margin.left - margin.right;
      var height = 300 - margin.top - margin.bottom;
      // Parse the date / time
      var parseDate = d3.time.format(" %Y-%m-%d %H:%M:%S ").parse;
      var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
      var y = d3.scale.linear().range([height, 0]);
      var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format("%d/%m"));
      var yAxis = d3.svg.axis().scale(y).orient("left").ticks(7);
      var div = d3.select("body").append("div");
      var svg = div.append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);
      var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
      ddd.forEach(function(d) {
        d.date = parseDate(d.date);
        d.value = +d.value;
      });
      x.domain(ddd.map(function(d) {
        return d.date;
      }));
      y.domain([0, d3.max(ddd, function(d) {
        return d.value;
      })]);
      g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).selectAll("text").style("text-anchor", "end").attr("dx", "-.8em").attr("dy", "-.55em").attr("transform", "rotate(-90)");
      g.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(0)").attr("y", -13).attr("dy", ".71em").style("text-anchor", "end").text("Count");
      g.selectAll("bar").data(ddd).enter().append("rect").style("fill", "steelblue").attr("x", function(d) {
        return x(d.date);
      }).attr("width", x.rangeBand()).attr("y", function(d) {
        return y(d.value);
      }).attr("height", function(d) {
        return height - y(d.value);
      });;
    }
    
    plot(data.map(a => Object.assign({}, a)));
    plot(data.map(a => Object.assign({}, a)));
  </script>
</body>

UPD: еще раз проверив ваш код, я понял, что вы можете просто извлечь этот код:

var parseDate = d3.time.format(" %Y-%m-%d %H:%M:%S ").parse;
data.forEach(function(d) {
  d.date = parseDate(d.date);
  d.value = +d.value;
});

из функции plot и поместите ее перед вызовом функции plot, вот рабочее решение:

<!DOCTYPE html>
<meta charset = "utf-8">

<head>
  <style>
    .axis {
      font: 10px sans-serif;
    }
    
    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
      shape-rendering: crispEdges;
    }
  </style>
</head>

<body>
  <script src = "http://d3js.org/d3.v3.min.js"></script>
  <script>
    var data = [];
    data.push({
      date: " 2019-03-25 00:00:00 ",
      value: 509
    });
    data.push({
      date: " 2019-03-26 00:00:00 ",
      value: 505
    });
    data.push({
      date: " 2019-03-27 00:00:00 ",
      value: 504
    });
    data.push({
      date: " 2019-03-28 00:00:00 ",
      value: 517
    });
    data.push({
      date: " 2019-03-29 00:00:00 ",
      value: 376
    });
    data.push({
      date: " 2019-03-30 00:00:00 ",
      value: 474
    });
    data.push({
      date: " 2019-03-31 00:00:00 ",
      value: 504
    });
    data.push({
      date: " 2019-04-01 00:00:00 ",
      value: 510
    });
    data.push({
      date: " 2019-04-02 00:00:00 ",
      value: 507
    });
    data.push({
      date: " 2019-04-03 00:00:00 ",
      value: 516
    });
    data.push({
      date: " 2019-04-04 00:00:00 ",
      value: 529
    });
    data.push({
      date: " 2019-04-05 00:00:00 ",
      value: 380
    });
    data.push({
      date: " 2019-04-06 00:00:00 ",
      value: 455
    });
    data.push({
      date: " 2019-04-07 00:00:00 ",
      value: 513
    });

    function plot(arg) {
      var ddd = arg;
      var margin = {
        top: 20,
        right: 20,
        bottom: 70,
        left: 40
      };
      var width = 600 - margin.left - margin.right;
      var height = 300 - margin.top - margin.bottom;


      var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
      var y = d3.scale.linear().range([height, 0]);
      var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format("%d/%m"));
      var yAxis = d3.svg.axis().scale(y).orient("left").ticks(7);
      var div = d3.select("body").append("div");
      var svg = div.append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);
      var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
      x.domain(ddd.map(function(d) {
        return d.date;
      }));
      y.domain([0, d3.max(ddd, function(d) {
        return d.value;
      })]);
      g.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis).selectAll("text").style("text-anchor", "end").attr("dx", "-.8em").attr("dy", "-.55em").attr("transform", "rotate(-90)");
      g.append("g").attr("class", "y axis").call(yAxis).append("text").attr("transform", "rotate(0)").attr("y", -13).attr("dy", ".71em").style("text-anchor", "end").text("Count");
      g.selectAll("bar").data(ddd).enter().append("rect").style("fill", "steelblue").attr("x", function(d) {
        return x(d.date);
      }).attr("width", x.rangeBand()).attr("y", function(d) {
        return y(d.value);
      }).attr("height", function(d) {
        return height - y(d.value);
      });;
    }
    
    var parseDate = d3.time.format(" %Y-%m-%d %H:%M:%S ").parse;
    data.forEach(function(d) {
      d.date = parseDate(d.date);
      d.value = +d.value;
    });
    
    plot(data);
    plot(data);
    
  </script>
</body>

Спасибо за исправление, я подозревал, что это портит данные, поэтому, когда я пишу "var ddd=arg;" я не копирую данные?

LAHOUEL Youssouf 09.04.2019 16:48

@LAHOUELYoussouf в этом случае вы меняете данные при присвоении значений объектам входного массива

Stranger in the Q 09.04.2019 16:54

@LAHOUELYoussouf Я проверил вашу функцию сюжета, похоже, вы можете просто извлечь ddd.forEach оттуда и поместить ее перед вызовом обеих функций сюжета. Я исправлю свой первый ответ после проверки на ПК. (сейчас пишу с мобильного) извините

Stranger in the Q 09.04.2019 17:20

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

LAHOUEL Youssouf 11.04.2019 12:12

Другие вопросы по теме