Я создаю трехлинейную диаграмму, используя D3v7, но отображается только одна. Я не могу понять, почему.
Это мой набор данных:
Текущий выход:
Посмотрите мой код ниже: // Настройка SVG
var svg = d3.select("body").append("svg")
.attr("width", width + paddingLeft + paddingRight)
.attr("height", height + paddingTop + paddingBottom)
.append("g")
.attr("transform",
"translate(" + paddingLeft + "," + paddingTop + ")");
// Настройка весов
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var colourScale = d3.scaleOrdinal(d3.schemeCategory10);
//Генератор строк
var line = d3.line()
.x(function(d) {return x(d.monthyear);
})
.y(function(d) { return y(d.total); });
// Загрузка данных
d3.csv('adidas_west_sales.csv').then(buildLineChart);
var parseTime = d3.timeParse("%Y-%m");
function buildLineChart(data)
{
data.forEach(function(d)
{
d.MonthYear = parseTime(d.MonthYear);
})
var salesMethods = data.columns.slice(1).map(function(method)
{
return { method: method,
values: data.map(function(d) {
return { monthyear: d.MonthYear,
total: parseFloat(d[method])
}
}
)}
});
console.info(salesMethods);
// Setup scales with data
x.domain(d3.extent(data, function(d) {
return d.MonthYear;}));
y.domain([
d3.min(salesMethods, function(b) {
return d3.min(b.values, function(d) {
return d.total;
});
}),
d3.max(salesMethods, function(b) {
return d3.max(b.values, function(d) {
return d.total;
});
})
]);
colourScale.domain(salesMethods.map(function(c) { return c.method}))
// Add Axis
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.ticks(24)
.tickFormat(d3.timeFormat("%b-%Y")))
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");;
svg.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("fill", "#000")
.text("Total Sale, $");
// Add lines
const lineGraph =
svg.selectAll("path")
.data(salesMethods)
.enter()
.append("path")
.attr('stroke', function(d, i) { return colourScale(i)})
.attr('stroke-width', 1.25)
.style("fill", "none")
.attr("d", function(d) { return line(d.values); });
}
salesMethods возвращает 3 значения: «Интернет», «В магазине», «Аутлет», но отображается только 1 строка.
Чего-то не хватает? Любая помощь будет принята с благодарностью!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Этот фрагмент кода может решить вашу проблему.
// Sample data
const data = [
{ monthYear: "2020-01", Instore: 5280000, Online: 143033, Outlet: 5525602 },
{ monthYear: "2020-02", Instore: 6588750, Online: 250233, Outlet: 3131293 },
{ monthYear: "2020-03", Instore: 7013750, Online: 181349, Outlet: 121259 },
{ monthYear: "2020-04", Instore: 9786250, Online: 251204, Outlet: 4461817 },
{ monthYear: "2020-05", Instore: 9032500, Online: 226795, Outlet: 4461817 },
{ monthYear: "2020-06", Instore: 8606250, Online: 223569, Outlet: 4461817 },
{ monthYear: "2020-07", Instore: 12758750, Online: 326500, Outlet: 4461817 },
{ monthYear: "2020-08", Instore: 3923750, Online: 94926, Outlet: 4461817 },
{ monthYear: "2020-11", Instore: 5280000, Online: 102780, Outlet: 4027729 },
{ monthYear: "2020-12", Instore: 5280000, Online: 117064, Outlet: 4461817 },
{ monthYear: "2021-01", Instore: 2300000, Online: 3454747, Outlet: 18660281 },
{ monthYear: "2021-02", Instore: 2573750, Online: 2974546, Outlet: 10743427 },
{ monthYear: "2021-03", Instore: 2851500, Online: 3283899, Outlet: 6204093 },
{ monthYear: "2021-04", Instore: 2795000, Online: 3608105, Outlet: 10785614 },
{ monthYear: "2021-05", Instore: 3563250, Online: 4503178, Outlet: 15244834 },
{ monthYear: "2021-06", Instore: 5426250, Online: 5837664, Outlet: 4712980 },
{ monthYear: "2021-07", Instore: 6420000, Online: 6422120, Outlet: 4985756 },
{ monthYear: "2021-08", Instore: 5280000, Online: 6369496, Outlet: 4260082 },
{ monthYear: "2021-09", Instore: 3145000, Online: 5210276, Outlet: 2950776 },
{ monthYear: "2021-10", Instore: 3471250, Online: 3986226, Outlet: 2442733 },
{ monthYear: "2021-11", Instore: 4271750, Online: 5183515, Outlet: 3509722 },
{ monthYear: "2021-12", Instore: 5576250, Online: 6302376, Outlet: 3737583 }
];
// Chart dimensions
const width = 800;
const height = 500;
const margin = { top: 20, right: 20, bottom: 50, left: 100 };
// Create SVG
const svg = d3.select("#chart")
.append("svg")
.attr("width", width)
.attr("height", height);
// Scales
const parseTime = d3.timeParse("%Y-%m");
const xScale = d3.scaleTime()
.domain(d3.extent(data, d => parseTime(d.monthYear)))
.range([margin.left, width - margin.right]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d3.max([d.Instore, d.Online, d.Outlet]))])
.range([height - margin.bottom, margin.top]);
// Line generator
const line = d3.line()
.x(d => xScale(parseTime(d.monthYear)))
.y(d => yScale(d.value));
// Colors
const colors = d3.scaleOrdinal()
.domain(["Instore", "Online", "Outlet"])
.range(["blue", "green", "red"]);
// Draw lines
["Instore", "Online", "Outlet"].forEach(type => {
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", colors(type))
.attr("stroke-width", 2)
.attr("d", d3.line()
.x(d => xScale(parseTime(d.monthYear)))
.y(d => yScale(d[type]))
);
});
// Axes
svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(yScale));
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xScale).tickFormat(d3.timeFormat("%Y-%m"))); #chart {
width: 800px;
height: 500px;
}<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<div id = "chart"></div>Я использую d3.v7 (7.8.5), пожалуйста, укажите точную версию d3 @vyclarks
это моя версия: <script src = "d3js.org/d3.v7.min.js"></script>
Я выполнил ваш код, но он не работает, ни одной строки не было показано. Как насчет моего кода? Я не знаю, в чем проблема
Ваши данные по сути представляют собой массив массивов. Когда вы приступите к добавлению строк, вам понадобится внешняя привязка данных, чтобы d3 выполнял итерацию по внешнему массиву:
const lineGraph = svg
.selectAll('.line')
.data(salesMethods)
.enter()
.append('g') //<-- create a `g` for each outer-array
.attr('class', 'line')
.append('path') //<-- then add the path
.attr('stroke', function (d, i) {
return colourScale(i);
})
.attr('stroke-width', 1.25)
.style('fill', 'none')
.attr('d', function (d, i) {
return line(d.values);
});
Запускающий код здесь.
Принятый ответ просто неверен, ваш код работает так, как есть.
Проблема в том, что вы выбираете два уже существующих пути — оси X и Y — и привязываете к ним данные.
Хотите убедиться, что это так? Просто выберите что-нибудь другое, и вы увидите, что ваш код работает:
const lineGraph =
svg.selectAll(".myPath")
.data(salesMethods)
.enter()
.append("path") etc...
Я использую D3 v7, этот код у меня не работает