#javascript #d3.js #charts #line
#javascript #d3.js #Диаграммы #линия
Вопрос:
Я хотел бы создать линейную диаграмму с двумя вертикальными линиями, которые отмечают начало (красным) и конец (зеленым) полосы высоких значений (10). Цвета этих линий должны быть назначены на основе свойства start_end в выходной переменной, например:
Есть идеи о том, как этого добиться? Пока это мой код (я использую d3 v6)
{
const svg = d3.select(DOM.svg(width, height))
svg.append('g').call(xAxis)
svg.append('g').call(yAxis)
svg.append("line")
.datum(output)
.attr("d", line)
.attr("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", 4)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("x1", xScale(output.timestamp))
.attr("y1", 0)
.attr("x2", xScale(output.timestamp))
.attr("y2", 10)
svg.append('path')
.datum(segment)
.attr('d', line)
.style('fill', 'none')
.style('stroke', 'black')
return svg.node()
}
output = [
{timestamp: "2020-09-25T04:00:54.857Z", jam_factor: 10, start_end: "start"}
{timestamp: "2020-09-29T18:02:23.282Z", jam_factor: 8.39212, start_end: "end"}
]
Комментарии:
1. Какую версию d3 вы используете? И что происходит, когда есть несколько полос?
2. Извините, забыл упомянуть, я использую версию 6
Ответ №1:
Я сгенерировал некоторые данные и покажу ниже, как добавить начальную и конечную линии общим способом.
const data = [0, 3, 5, 7, 5, 4, 6, 7, 10, 10, 10, 10, 7, 5, 7, 6, 8, 9, 9, 10, 10, 10, 10, 10, 10, 9, 5, 6, 4, 6, 8, 10, 10, 9].map((v, i) => {
const now = new Date();
now.setDate(i);
return {
timestamp: now,
value: v,
};
});
// Find all places where we first hit or stop hitting 10
let active = false;
data.forEach((d, i) => {
if (d.value === 10) {
if (!active) {
d.start = true;
active = true;
}
} else {
// The previous was the last active one
if (active) {
data[i - 1].end = true;
active = false;
}
}
});
const width = 600,
height = 300;
const x = d3.scaleTime()
.domain(d3.extent(data, d => d.timestamp))
.range([0, width]);
const y = d3.scaleLinear()
.domain([0, 10])
.range([height - 10, 10]);
const line = d3.line()
.x(d => x(d.timestamp))
.y(d => y(d.value))
const svg = d3.select('svg')
.attr('width', width)
.attr('height', height)
svg.append("path")
.datum(data)
.attr("d", line)
.style("stroke", "steelblue")
.style("stroke-width", 2)
.style("fill", "none");
svg.selectAll("line")
.data(data.filter(d => d.start || d.end))
.enter()
.append("line")
.attr("x1", d => x(d.timestamp))
.attr("x2", d => x(d.timestamp))
.attr("y1", y.range()[0])
.attr("y2", y.range()[1])
.attr("stroke", d => d.start ? "green" : "red")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<svg></svg>