Добавленные полосы не будут отображаться на элементе svg

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

Единственное, что я действительно думал о том, чтобы попытаться изменить выбор svg на группу вместо выбора всех прямоугольников, если там что-то облажалось.

Этот блок создает элемент svg, вводит первый CSV-файл и добавляет прямоугольники на диаграмму. Моя единственная мысль о том, в чем может быть проблема, заключается в том, что она находится внутри функции, но если я возьму ее из функции, как мне привязать к ним данные?

//Creating SVG Element
var chart_w = 1000,
chart_h = 500,
chart_pad_x = 40,
chart_pad_y = 20;

var svg = d3.select('#chart')
    .append('svg')
    .attr('width', chart_w)
    .attr('height', chart_h);

//Defining Scales
var x_scale = d3.scaleBand().range([chart_pad_x, chart_w - 
chart_pad_x]).padding(0.2);
var y_scale = d3.scaleLinear().range([chart_pad_y, chart_h - 
chart_pad_y]);

//Data-------------------------------------------------------------------
d3.csv('data.csv').then(function(data){
        console.info(data);
        generate(data);  });

function generate(data){
//Scale domains
x_scale.domain(d3.extent(data, function(d){ return d }));
y_scale.domain([0, d3.max(data, function(d){ return d })]);

//Create Bars
svg.select('rect')
        .data(data)
        .enter()
        .append('rect')
        .attr('x', function(d, i){
            return x_scale(i);
        })
        .attr('y', function(d){
             return y_scale(d);
        })
        .attr('width', x_scale.bandwidth())

        .attr('height', function(d){
            return y_scale(d);
        })
        .attr('transform',
          "translate(0,0)")
        .attr('fill', '#03658C')

'''

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

Поведение ключевого слова "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) для оценки ваших знаний,...
0
0
33
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Попробуйте использовать следующее:

svg.selectAll('rect')
    .data(data)

Если вы используете svg.select, это сделает привязку данных только к первому найденному элементу.

d3.select(selector): Selects the first element that matches the specified selector string. If no elements match the selector, returns an empty selection. If multiple elements match the selector, only the first matching element (in document order) will be selected. For example, to select the first anchor element:

Это должно быть ясно, если вы проверите узлы DOM.

Чтобы решить эту проблему, давайте изменим некоторые вещи в вашем коде:

Давайте создадим фиктивную функцию выборки:

(function simulateCSVFetch() {
    const data = [1,2,3,4,5];
    generate(data);
})();

Вы также используете scaleBand с неполным доменом, используя функцию extent:

d3.extent(): Returns the minimum and maximum value in the given iterable using natural order. If the iterable contains no comparable values, returns [undefined, undefined]. An optional accessor function may be specified, which is equivalent to calling Array.from before computing the extent.

x_scale.domain(d3.extent(data, function(d) { // cant use extent since we are using a scaleBand, we need to pass the whole domain
   return d;
}));
console.info(x_scale.domain()) // [min, max]

Для scaleBand требуется сопоставление всего домена.

Band scales are typically used for bar charts with an ordinal or categorical dimension. The unknown value of a band scale is effectively undefined: they do not allow implicit domain construction.

Если мы продолжим использовать эту шкалу, мы получим только два значения для нашей шкалы x. Давайте исправим это с правильным доменом:

x_scale.domain(data);

Наконец, используйте selectAll для создания привязки данных:

 svg.selectAll('rect')
 .data(data)
 .enter()
 .append('rect')
 .attr('x', function(d, i) {
   return x_scale(d);
 })
 .attr('y', function(d) {
   return chart_h - y_scale(d); // fix y positioning
 })
 .attr('width', x_scale.bandwidth())

 .attr('height', function(d) {
   return y_scale(d);
 })
 .attr('fill', '#03658C');

Это должно сработать.

Полный код:

 var chart_w = 1000,
   chart_h = 500,
   chart_pad_x = 40,
   chart_pad_y = 20;

 var svg = d3
   .select('#chart')
   .append('svg')
   .style('background', '#f9f9f9')
   .style('border', '1px solid #cacaca')
   .attr('width', chart_w)
   .attr('height', chart_h);

 //Defining Scales
 var x_scale = d3.scaleBand()
   .range([chart_pad_x, chart_w - chart_pad_x])
   .padding(0.2);
 var y_scale = d3.scaleLinear()
   .range([chart_pad_y, chart_h - chart_pad_y]);

 //Data-------------------------------------------------------------------

 (function simulateCSVFetch() {
  const data = [1,2,3,4,5];
  generate(data);
 })();



 function generate(data) {
 console.info(d3.extent(data, function(d) { return d }));
   //Scale domains
   x_scale.domain(d3.extent(data, function(d) { // cant use extent since we are using a scaleBand, we need to pass the whole domain
     return d;
   }));
 // Band scales are typically used for bar charts with an ordinal or categorical dimension. The unknown value of a band scale is effectively undefined: they do not allow implicit domain construction.
   x_scale.domain(data);
   y_scale.domain([0, d3.max(data, function(d) {
     return d
   })]);

   //Create Bars
   svg.selectAll('rect')
     .data(data)
     .enter()
     .append('rect')
     .attr('x', function(d, i) {
       return x_scale(d);
     })
     .attr('y', function(d) {
       return chart_h - y_scale(d); // fix y positioning
     })
     .attr('width', x_scale.bandwidth())

     .attr('height', function(d) {
       return y_scale(d);
     })
     .attr('fill', '#03658C');
 }

Рабочий jsfiddle здесь


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