Необходимо создать линию в пределах осей х и у в d3 v5 - PullRequest
0 голосов
/ 10 января 2020

У меня есть гистограмма, созданная с помощью d3 v5, для которой в качестве «предела» должна быть прямая линия в зависимости от заданного значения c y.

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

enter image description here

Вот код чтобы создать график

(async ()=> {

const response = await fetch('https://api);
const myJson = await response.json();
//need myJson.DailyDelvs to be the y value of the line

// set the dimensions and margins of the graph
var margin = {top: 30, right: 30, bottom: 70, left: 60},
    width = 400 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom
    tip = d3.tip()
    .attr('class', 'd3-tip')
    .html(function(d) { return "DAY: "+d.DIA+"<br/>PO: "+d.PO_ID })

// append the svg object to the body of the page
var svg = d3.select("#dailyDeliveryVolume")
  .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")")
  .call(tip)

  var datos
// get the data
d3.json("https://api2").then(function(data) {

datos = data
d3.select("#dailyDeliveryVolume_spinner").remove();

var x = d3.scaleBand()
.range([ 0, width ])
.domain([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31])
.padding(0.05);

var xAxis = d3.axisBottom(x)
.tickValues(x.domain().filter(function(d,i){ return !(i%2)}));

svg.append("g")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis)

var y = d3.scaleLinear()
.domain([0, d3.max(data.STD, function(d) { return +d.PO_ID })])
.range([ height, 0]);

svg.append("g")
  .call(d3.axisLeft(y))

// Bars
svg.selectAll("mybar")
  .data(data.STD)
  .enter()
  .append("rect")
    .attr("x", function(d) { return x(d.DIA); })
    .attr("y", function(d) { return y(d.PO_ID); })
    .attr("width", x.bandwidth())
    .attr("height", function(d) { return height - y(d.PO_ID); })
    .attr("fill", "#69b3a2")
    .attr("border-color", "black")
    .on("mouseover", tip.show)
    .on("mouseleave", tip.hide )

})
})()

Чтобы создать линию, я попробовал следующий код, сразу после добавления баров, что вызывает ошибку


var linea = drawLine(svg, x, y, data.STD);

var drawLine = function(svg, x, y, data) {
  var lineFunc = d3.line()
    .x(function(obj) {
      return x(obj.DIA);
    })
    .y(function(obj) {
      return y(obj.PO_ID);
    });

  var linea = svg.append("linea") //SVG Paths represent the outline of a shape that can be stroked, filled, used as a clipping path, or any combination of all three. We can draw rectangles, circles, ellipses, polylines, polygons, straight lines, and curves through path
  .attr("d", lineFunc(data))
  .attr("stroke", '#87CEEB')
  .attr("stroke-width", 3)
  .attr("fill", "black");

  return linea;
};

dailyDeliveryVolume. js: 64 Uncaught (в обещании) TypeError: drawLine не является функцией в dailyDeliveryVolume. js: 64

Я также пытался напрямую добавить строку в svg с помощью фиксированные атрибуты x1, x2, y1 и y2, но, кажется, это сделано на основе всего контейнера и не может соответствовать значениям осей x и y.

Цель состоит в том, что мои Json .DailyDelvs - это значение y (основанное на значениях шкалы y), а затем оно является прямым по всей ширине.

1 Ответ

0 голосов
/ 11 января 2020

Одна проблема заключается в том, что вам нужно вызывать функцию (var linea = drawLine(...)) после определения функции (var drawLine = ...).

Я думаю, вы также можете упростить то, что вы делаете, нарисовав <line> напрямую:

svg.append("line")
    .attr("x1", x(0))
    .attr("x2", x(31))
    .attr("y1", y(obj.PO_ID))
    .attr("y2", y(obj.PO_ID))
    .attr("stroke", '#87CEEB')
    .attr("stroke-width", 3)
    .attr("fill", "black");

(я не уверен, какое значение вы пытаетесь использовать для оси y, но похоже, что оно должно быть похоже на приведенное выше ...)

...