Ваши проблемы l ie здесь:
svg.append('bar')
.attr("fill", "lightskyblue")
.selectAll("rect")
.data(data)
.join("rect")
Вы добавляете элемент bar
в SVG - это не допустимый элемент SVG, и он не будет отображать и будут его дети (прямоугольники, которые вы хотите нарисовать).
Я просто собираюсь использовать выбор enter
(объединение сочетает в себе функциональность ввода / выхода / обновления, но мы должны сначала использовать функцию ввода):
svg
.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("...")
Выбор ввода создает элемент в DOM для каждого элемента в массиве данных, который еще не имеет соответствующего элемента в DOM. Я могу выбрать все элементы rect
с помощью selectAll("rect")
, но для каждого выбранного мной элемента, который уже существует, один элемент в массиве данных не будет введен. Поэтому я ничего не выбираю: .selectAll(null)
, который создает пустой выбор, не содержащий элементов DOM. Таким образом, вводится каждый элемент массива данных независимо от того, что уже находится в DOM.
В вашем случае использование selectAll("rect")
нормально, так как rect
не будет выбрано * Теперь я связываю массив данных: .data(data)
И тогда я получаю доступ к вводу выбора: .enter()
. Это возвращает выбор заполнителей. Поскольку мы ничего не выбрали, для каждого элемента массива данных создается один заполнитель. Теперь я могу добавить элементы SVG с .append("rect")
. С этим у меня есть выбор вновь созданных прямоугольников. Теперь я могу изменить их по своему усмотрению, например, используя привязанные данные, чтобы установить их ширину / высоту, x / y и т. Д. c.
. Для простоты я представил только использование введите выбор здесь. Если я использую selectAll("rect")
и ректы уже существуют, теперь у меня есть потенциальные возможности обновления и / или выхода - что позволило бы обновить существующие прямоугольники, для которых есть соответствующие элементы в массиве данных, или выйти из элементов, для которых больше нет соответствующих элементы в массиве данных.
var margin = { top: 30, right: 30, bottom: 30, left: 30 },
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var svg = d3.select('body').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 + ')');
//defines the x-axis which is based on a numerical format
var xScale = d3.scaleLinear()
.rangeRound([0, width]);
//defines the y-axis which is based on a numerical format
var yScale = d3.scaleLinear()
.rangeRound([height, 0]);
d3.csv("http://raw.githubusercontent.com/naija-queen/Raw-Data/master/crashing.csv").then(function (data) {
//sets the domain of the x-axis
xScale.domain([0, d3.max(data, function(d){
return (Number(d.episode));
})])
//sets the domain of the y-axis
yScale.domain([0, d3.max(data, function(d){
return (Number(d.percent));
})])
//draws the x-axis
svg.append('g')
.attr("transform", "translate(0," + height + ")")
//.ticks() command allows you to define how many ticks you want to see in the visualization
.call(d3.axisBottom(xScale).ticks(16))
//draws the y-axis
svg.append("g")
//for some reason moving arround the function call below makes the y-axis disappear
.call(d3.axisLeft(yScale))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("text-anchor", "end")
.text("Percent Watched");
//parts of a bar chart
svg
.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("fill", "lightskyblue")
// d => is basically function(d){}
.attr("x", d => xScale(Number(d.episode)))
.attr("y", d => yScale(Number(d.percent)))
.attr("width", 20)
.attr("height", d => yScale(0) - yScale(Number(d.percent)));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Кроме того, если вы хотите, чтобы введенные вами элементы содержались в родительском g
, вы можете использовать selectAll
вложенный g
, такой как с:
svg
.append("g")
.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("...")