гистограмма d3.js не показывает бары

Для меня работало следующее:

var form_enabled = true;
$().ready(function(){
       // allow the user to submit the form only once each time the page loads
       $('#form_id').on('submit', function(){
               if (form_enabled) {
                       form_enabled = false;
                       return true;
               }

               return false;
        });
});

Это отменяет событие отправки, если пользователь пытается отправить форму несколько раз (нажав кнопку отправки, нажав Enter и т. д.).

0
задан pmkro 18 March 2019 в 18:21
поделиться

2 ответа

Ваш scaleBand().domain() должен быть массивом для Xscale. В моем решении я выбираю индексы значений в качестве массива. Вы можете сопоставить свои данные (обычно массив объектов) с другими значениями объектов в массиве. Кроме того, было несколько других проблем с масштабированием с точки зрения высоты и ширины фактических стержней и их расположения. Имейте в виду, что источник SVG - это верхний левый угол, и все относительно этого.

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

var data = [1, 2, 3, 4, 5];
var svg = d3.select("svg");
var margin = 100,
  width = svg.attr("width") - margin,
  height = svg.attr("height") - margin;
var Xscale = d3.scaleBand()
  .domain(data.map((e,i) => i)) //returns array [0,1,2,3,4] for the index of the values
  .range([0, width])
  .padding(0.2);
var dmax = d3.max(data) //calculates the max value of the data
var Yscale = d3.scaleLinear()
  .domain([0, dmax])
  .range([height, 0]);
  
var g = svg.append("g")
  .attr("transform", "translate(" + 50 + "," + 50 + ")");

var x = g.append("g")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(Xscale).tickFormat(function(d) {
    return d;
  }).ticks(10))
 .append("text")
 .attr("x", 6)
 .attr("text-anchor", "end")
 .text("index");

var y = g.append("g")
  .call(d3.axisLeft(Yscale).tickFormat(function(d) {
    return d;
  }).ticks(10))
  .append("text")
  .attr("y", 6)
  .attr("dy", "0.71em")
  .attr("text-anchor", "end")
  .text("value");

g.selectAll(".bar")
  .data(data)
  .enter().append("rect")
  .attr("class", "bar")
  .attr("x", function(d, i){ return Xscale(i)}) //move the bar to the x position where it should appear
  .attr("y", function(d, i) { return Yscale(d); }) //move the bar from the top down to the level of the value.
  .attr("width", Xscale.bandwidth() ) //the width of the bar is the width between the points on the x-axis 
  .attr("height", function(d, i) {
    return Yscale(dmax-d);
  }); // the height of the points is calculated based on the scale and the difference between this point and the max value of the data.
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>Bar chart with D3.js</title>
  <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
  <script src="https://d3js.org/d3.v5.min.js"></script>

</head>

<body>
  <div id='layout'>
    <h2>Bar chart example</h2>
    <div class='container'>
      <svg class="chart" height="500" width="1000" />
    </div>
  </div>
  <p>Why this is not working?? </p>
</body>

</html>

0
ответ дан Coola 18 March 2019 в 18:21
поделиться

Я рекомендую вам прочитать эту статью. Это очень хорошо объясняет, как использовать гистограммы. https://blog.risingstack.com/d3-js-tutorial-bar-charts-with-javascript/

Я использовал ваш код и сделал простой пример. https://codepen.io/mp-9007/pen/jJpEWY

Основные проблемы связаны с возвращаемыми значениями x, y и height; Вы должны указать координаты x и y в области графика. Рисование гистограммы аналогично рисованию на декартовой плоскости, вы должны указать координаты, где начать полосу, ширину полосы и ее высоту. Источник плана находится в левом верхнем углу изображения.

.attr("x", function(d, i) { //d = input data, i = index of it
    return Xscale(d); //The scaling function returns the coordinate for a given domain value.
})
.attr("y", function(d, i) { //d = input data, i = index of it
    return Yscale(d); //The scaling function returns the coordinate for a given domain value.
})
.attr("width", Xscale.bandwidth())
.attr("height", function(d, i) { //d = input data, i = index of it
    return height - Yscale(d); //The computed y coordinate has to be subtracted from the height of the chart to get the correct representation of the value as a column.
});

Кроме того, домен для оси х можно рассматривать как категории. В вашем коде вы указали только две категории: 0 и data.length. Предоставление массива решило эту проблему.

var Xscale = d3.scaleBand().domain(data)
0
ответ дан mp9007 18 March 2019 в 18:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: