Наложение круга, текста и т. Д. На многосерийные линии d3.js

У меня есть код линейной диаграммы серии multi с небольшими изменениями для поддержки моего набора данных. Это то, что я хочу сделать, и ни одно решение, на которое я смотрел, кажется, не работает должным образом для меня. Я хочу наложить некоторый элемент (круг, прямоугольник, скрытый, какой бы то ни было) на каждую точку линии так, чтобы я мог затем прикрепить элемент наведения мыши к этой точке, чтобы отобразить окно с данными, содержащими d.time, d.jobID и как много чего отличается от среднего. Если возможно, я бы хотел, чтобы решение делало это только с основной линией (изменяющейся линией), а не с двумя линиями, нарисованными для представления среднего значения. Здесь у меня есть изображение графика как есть для визуального осмотра. Если это не сработает, я также приложил его.

Я разместил немного кода ниже.

d3.tsv("values.tsv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "time" && key !==   "jobID"; }));

data.forEach(function(d) {
  d.time = parseDate(d.time);
  d.jobID = parseInt(d.jobID);
});

var points = color.domain().map(function(name) {
return {
  name: name,
  values: data.map(function(d) {
    return {time: d.time, jobID: d.jobID, value: parseFloat(d[name],10)};
  })
};
});

....

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

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
.append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 7)
  .attr("dy", ".71em")
  .style("text-anchor", "end")
  .text("mbps");

var point = svg.selectAll(".point")
  .data(points)
.enter().append("g")
  .attr("class", "point");

point.append("path")
  .attr("class", "line")
  .attr("d", function(d) { return line(d.values); })
  .style("stroke", function(d) { return color(d.name); });

point.append("text")
  .datum(function(d) { return {name: d.name, jobID: d.jobID, value: d.values[d.values.length - 1]}; })
  .attr("transform", function(d) { return "translate(" + x(d.value.time) + "," + y(d.value.value) + ")"; })
  .attr("x", 6)
  .attr("dy", ".7em")
  .text(function(d) { return d.name; });
});

Я уже пробовал следующий код, чтобы посмотреть, работает ли он с моей реализацией:

point.append("svg:circle")
     .attr("stroke", "black")
     .attr("fill", function(d, i) { return "black" })
     .attr("cx", function(d, i) { return x(d.time) })
     .attr("cy", function(d, i) { return y(d.value) })
     .attr("r", function(d, i) { return 3 });

Спасибо всем за вашу помощь заранее. D3.JS выглядит довольно крутой работой, и мне повезло, что она у меня есть.

РЕДАКТИРОВАТЬ: jsfiddle

1 ответ

Решение

Хитрость заключается в том, чтобы снова передать данные в выборку и затем обработать результат этого. Взгляните на учебник Майка для некоторых фон и примеры.

Я изменил ваш jsfiddle, чтобы добавить круги здесь. Прикрепление svg:title элементы или что-то еще, чтобы показать больше информации, должно быть простым. Обратите внимание, что я изменил ваш код, чтобы немного создать точки данных, чтобы включить имя для каждого элемента. Таким образом, необходим только один дополнительный уровень выбора (обработайте все точки одинаково и добавьте их за один проход). Более чистым способом решения этой проблемы с точки зрения разработки кода было бы иметь 2 дополнительных уровня - сначала выделите точки для отдельной линии (и добавьте svg:g элемент, чтобы сгруппировать их), а затем добавить точки в этой группе. Это сделало бы код немного более сложным и трудным для понимания.

Другие вопросы по тегам