Я пытаюсь создать диаграмму, похожую на фасет, которая генерируется динамически.Например, у меня 3 сегмента и годовой объем продаж.Я хочу иметь 3 гистограммы одна под другой, показывающая продажи по годам.Мне удалось создать гистограмму и сделать ее динамичной, но только если у меня есть предопределенный тег в моем index.html.Я хочу создать тег из моего js-файла, чтобы я мог установить все свойства оттуда.Сейчас проблема в том, что хотя я вижу все элементы на вкладке Chrome elements, на самой странице ничего нет.
Буду признателен за любую помощь и советы, поскольку я веб-разработчик noob:)
Мои примеры данных
{
"segment": "Pro",
"values": [
{ "year": 2017, "value": 100 },
{ "year": 2018, "value": 360 },
{ "year": 2019, "value": 850 }
]
},
{
"segment": "Cash",
"values": [
{ "year": 2017, "value": 180 },
{ "year": 2018, "value": 140 },
{ "year": 2019, "value": 100 }
]
},
{
"segment": "Retail",
"values": [
{ "year": 2017, "value": 200 },
{ "year": 2018, "value": 350 },
{ "year": 2019, "value": 650 }
]
}
]
И код:
(function f() {
const svgb0 = d3.select("svg");
const widthb = +svgb0.attr("width");
const heightb = +svgb0.attr("height");
const render = sample => {
const len = sample.length;
const margin = { top: 100, right: 100, bottom: 100, left: 100 };
const Innerwidth = widthb - margin.right - margin.left;
const innerHeight = heightb / len - margin.top - margin.bottom;
for (var n = 0; n < len; n++) {
const svgb1 = document.createElement(`g`);
svgb1.className = `seg${n}`;
d3.select(svgb1)
.attr("width", widthb)
.attr("height", heightb / len)
.attr("transform", `translate(${0},${n * innerHeight})`);
document.getElementById("bars").appendChild(svgb1);
const svgb = svgb0.select(`.seg${n}`);
const data = sample[n].values;
data.forEach(el => {
el.value = +el.value;
//el.year = d3.timeParse("%Y")(el.year);
});
const xScale = d3
.scaleBand()
.domain(data.map(d => d.year))
.range([0, Innerwidth])
.padding(0.2);
const yScale = d3
.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([innerHeight, 0]);
const g1 = svgb
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
g1.append("g").call(d3.axisLeft(yScale));
const xAxis = d3.axisBottom(xScale);
g1.append("g")
.call(xAxis)
.attr("transform", `translate(${0},${innerHeight})`);
g1.selectAll("rect")
.data(data)
.enter()
.append("rect")
.style("fill", "steelblue")
.attr("x", d => xScale(d.year))
.attr("y", d => yScale(d.value))
.attr("width", xScale.bandwidth())
.attr("height", d => innerHeight - yScale(d.value))
.attr("class", `seg${n}`);
//g1.attr("transform",`translate(${0},${n*innerHeight})`)
}
};
d3.json("sample.json").then(function(sample) {
render(sample);
});
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width"
/>
<meta http-equiv="X-AU-Compatible" content="ie=edge" />
<title>Hello world!</title>
<script src="http://d3js.org/d3.v5.js"></script>
</head>
<body>
<h1>Hello world!</h1>
<svg class="bars" id="bars" width="1000" height="5000">
</svg>
<script src="ros1.js"></script>
</body>
</html>