Проблема загрузки данных в таблице с использованием D3 версии 4 - PullRequest
2 голосов
/ 06 мая 2020

У меня есть таблица, которая будет заполнена данными, когда я нажму кнопку. Ниже приведен фрагмент:

function myFunction() {
	myTable = d3.select("#mytable");
	myTable.selectAll("td").remove();
	var rows = add_temp_rows(myTable);
}

function add_temp_rows(table) {
 	data = [{"a" : get_rand_temp(),
           "b" : get_rand_temp()
          }, 
          {"a" : get_rand_temp(),
           "b" : get_rand_temp()
          },
          {"a" : get_rand_temp(),
           "b" : get_rand_temp()
          }];
	var rows = table
		.select('tbody')
		.selectAll('tr')
		.data(data);
		
	rows.enter()
		.append("tr")
		.merge(rows);

	rows.exit().remove();
  
  rows.selectAll("td")
      .data(function (d) {
        return [d.a, d.b];
      })
      .enter()
      .append('td')
      .text(function (d) {
        return d;
      });
  return rows;
}

function get_rand_temp() {
	var precision = 100;
	return Math.floor(Math.random() * (10 * precision - 1 * precision) + 1 * precision) / (1*precision);
}
<!DOCTYPE html>

<head>
    <title>Test</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
        integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>

<body>

    <div class="container">
      
        <div class="row">
            <button onclick="myFunction()">Try it</button>
            <div id="FilterableTable2" class="col-8">
                <div class="table-responsive">
                    <table class="table table-striped table-dark" id="mytable">
                        <thead class='thead-dark'>
                            <tr>
                                <th>Col1</th>
                                <th>Col2</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td>test</td>
                                <td>test2</td>
                            </tr>
                            <tr>
                                <td>test3</td>
                                <td>test4</td>
                            </tr>
                            <!--<tr>
                                <td>test</td>
                                <td>test2</td>
                            </tr>
                            <tr>
                                <td>test3</td>
                                <td>test4</td>
                            </tr>
                            -->
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>


    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"
        integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  
    <!-- D3 -->
  
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <!-- <script src="https://d3js.org/d3.v5.min.js"></script> -->

    <script src="js/main.js"></script>
</body>

Теперь у меня есть несколько проблем:

  1. Если таблица пуста в начале, первый щелчок не заполнит таблица, но второй щелчок будет заполнен правильно. Хотя я проверил Chrome и увидел, что первый щелчок все еще обрабатывается, и некоторые данные были напечатаны.
  2. Если я жестко закодирую некоторые начальные значения в HTML, а количество жестко закодированных строк будет равно или больше, чем количество новых данных, тогда он будет работать нормально с первого щелчка.
  3. Если исходных жестко закодированных строк меньше (но не пустых), первый щелчок изменит данные этих строк но не будет добавлять больше строк для соответствия данным. Но второй щелчок вперед добавит правильное количество строк.

Могу я узнать, как это исправить? Я перехожу с D3 v3 на v4, есть много критических изменений. В идеале я хочу, чтобы каждый щелчок изменял таблицу для отображения правильных строк данных.

1 Ответ

2 голосов
/ 07 мая 2020

Ошибка заключается в том, что во время первого вызова строки объекта не содержат новых tr, созданных с помощью .enter (), хотя команда .merge (row) d3 js .org . Таким образом, rows.selectAll ("td") не влияет на новые tr. Вновь созданные tr выбираются во время второго вызова.

Таким образом, чтобы действовать сразу после первого вызова, решение состоит в вызове .selectAll ("td") сразу после .merge (row).

    //...
    rows.enter()
        .append("tr")
        .merge(rows)
        .selectAll("td")
        .data(function (d) {
            return [d.a, d.b];
        })
        .enter()
        .append('td')
        .text(function (d) {
            return d;
        });
    //...

<!DOCTYPE html>

<head>
    <title>Test</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
        integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>

<body>

    <div class="container">
      
        <div class="row">
            <button onclick="myFunction()">Try it</button>
            <div id="FilterableTable2" class="col-8">
                <div class="table-responsive">
                    <table class="table table-striped table-dark" id="mytable">
                        <thead class='thead-dark'>
                            <tr>
                                <th>Col1</th>
                                <th>Col2</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td>test</td>
                                <td>test2</td>
                            </tr>
                            <tr>
                                <td>test3</td>
                                <td>test4</td>
                            </tr>
                            <!--<tr>
                                <td>test</td>
                                <td>test2</td>
                            </tr>
                            <tr>
                                <td>test3</td>
                                <td>test4</td>
                            </tr>
                            -->
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>


    <!-- jQuery -->
    <!-- script src="https://code.jquery.com/jquery-3.5.1.min.js"
        integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script -->
  
    <!-- D3 -->
  
    <!-- script src="https://d3js.org/d3.v4.min.js"></script -->
    <script src="https://d3js.org/d3.v5.min.js"></script>

    <!-- script src="js/main.js"></script -->

<script>
function myFunction() {
	myTable = d3.select("#mytable");
	myTable.selectAll("td").remove();
	var rows = add_temp_rows(myTable);
}

function add_temp_rows(table) {
 	data = [{"a" : get_rand_temp(),
           "b" : get_rand_temp()
          }, 
          {"a" : get_rand_temp(),
           "b" : get_rand_temp()
          },
          {"a" : get_rand_temp(),
           "b" : get_rand_temp()
          }];
	var rows = table
		.select('tbody')
		.selectAll('tr')
		.data(data);
		
	rows.enter()
		.append("tr")
		.merge(rows)
    .selectAll("td")
      .data(function (d) {
        return [d.a, d.b];
      })
      .enter()
      .append('td')
      .text(function (d) {
        return d;
      });

	rows.exit().remove();
  
  return rows;
}

function get_rand_temp() {
	var precision = 100;
	return Math.floor(Math.random() * (10 * precision - 1 * precision) + 1 * precision) / (1*precision);
}
</script>
</body>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...