D3js: «Как добавить разные пути для разных значений?» - PullRequest
0 голосов
/ 15 января 2019

У меня есть набор данных строк:

-------------------------------------
service | timestamp           | value
-------------------------------------
4       | 2019-01-15 xx:xx:xx | 14
-------------------------------------
4       | 2019-01-15 xx:xx:xx | 14  
-------------------------------------
8       | 2019-01-15 xx:xx:xx | 18  
-------------------------------------
8       | 2019-01-15 xx:xx:xx | 18 
-------------------------------------
etc.

Теперь я хочу «нарисовать» отдельные линии для сервиса 4 и 8.

Я включил фильтр:

var servData = data.filter(function(d) {
    return d.service == 4
});

...

svg.append("path")
 .datum(servData) 
 .attr("class", "line") 
 .attr("d", line);

Это работает, если я напишу фильтр и добавлю для каждого уникального сервиса, но я хочу динамически добавлять сервисы.

Например: Сервис имеет от 2 до 5 различных значений

Добавить 2–5 «путей» для каждого уникального номера услуги.

Как я могу добавить пути к графике SVG

без добавления всех служб в жестком коде?

Спасибо.

1 Ответ

0 голосов
/ 15 января 2019

Проверьте общий шаблон обновления

var paths = svg.selectAll('path')
  .data(pathsData)

var pathsEnter = paths.enter()
  .append('path')
  .attr("class", "line") 
  .attr('d', line)

Редактировать

На основе фотографии, которой вы поделились в комментариях

  • вычисляет уникальный массив всех значений service. (в вашем примере это будет [4, 8], но будет управляться данными.)

  • Затем используйте этот массив в качестве данных для группы service lines.

  • Расположите каждую строку в соответствии с вашей шкалой y.

  • Бонус: создайте цветовую шкалу для динамического определения цвета обводки линии на основе ее значения в массиве значений обслуживания.

const data = [{service: 4, otherData: '...'},{service: 4, otherData: '...'},{service: 8, otherData: '...'},{service: 8, otherData: '...'},{service: 12, otherData: '...'},{service: 12, otherData: '...'}
]

// Get a unique array from data
const serviceData = Array.from(new Set(data.map(a => a.service)));

// create a color scale if you need
const color = d3.scaleLinear().domain(serviceData).interpolate(d3.interpolateHcl).range([d3.rgb("#ff0000"), d3.rgb('#257c00')]);

const width = 500;
const height = 300;
const svg = d3.select('body').append('svg').attr('width', width).attr('height', height)

// Bind to data
const lines = svg.append('g').attr("class", "service-lines-group").selectAll('line')
  .data(serviceData)

// Enter selection - create lines for each data point
const linesEnter = lines.enter()
  .append('line')
  .attr("class", "service-line")
  .attr('x1', 0)
  .attr('x2', width)
  .attr('y1', d => d * 10)
  .attr('y2', d => d * 10)
  .attr('stroke', (d, i) => {
    return color(d)
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
...