Имитация звукового сигнала с помощью d3 - PullRequest
0 голосов
/ 25 февраля 2019

Я делаю визуализацию, показывающую наиболее распространенные жанры для концертов в данном городе.В настоящее время я отображаю данные с помощью диаграммы области d3.

data visualised using only area chart

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

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

Здесь все выглядит хорошо: Dublin, Ireland

Не очень хорошо здесь: London, UK

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

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

Кто-нибудь получил какие-либо предложения?Моей целью было бы получить визуализацию примерно так:

desired outcome - more details

desired outcome - less details

1 Ответ

0 голосов
/ 25 февраля 2019

Одним из подходов является использование данных не для создания диаграммы, а для создания зубчатой ​​линейной шкалы x -> y.Затем сгенерируйте желаемое количество прямоугольников и сопоставьте их индексы с позицией x.Отдыхать просто - переходите по индексам, сопоставляйте их с x, сопоставляйте полученный x с y, и все готово.

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <style>
    body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
  </style>
</head>

<body>
  <script>
    
    var data = [{
      x: 1,
      y: 2
    }, {
      x: 5,
      y: 10
    }, {
      x: 15,
      y: 5
    }, {
      x: 20,
      y: 13
    }, {
      x: 25,
      y: 4
    }];
    
    var rectCount = 8;
    
    var yScale = d3.scaleLinear()
    	.domain(data.map(function(d){ return d.x; }))
    	.range(data.map(function(d){ return d.y; }));
    
    var xScale = d3.scaleBand()
    	.domain(d3.range(rectCount))
    	.paddingInner(0.5)
    	.range([d3.min(data, function(d) {return d.x; }),
              d3.max(data, function(d) {return d.x; })]);
    
    var svg = d3.select("body").append("svg")
      .attr("width", 100)
      .attr("height", 100)
    	.attr('viewBox', '-5 -20 35 40');

    var chartData = d3.range(rectCount).map(function(i){
      var x = xScale(i);
      var width = xScale.bandwidth();
      var y = yScale(x);
      var height = y*2;
      return {
        x: x,
        y: y,
        width: width,
        height: height
      };
    });
    
    svg.selectAll('rect')
    	.data(chartData)
    .enter()
    	.append('rect')
    	.attr('x', function(d) { return d.x; })
    	.attr('y', function(d) { return -d.y; })
    	.attr('width', function(d) { return d.width; })
    	.attr('height', function(d) { return d.height; })

  </script>
</body>
...