Если вы хотите, чтобы ваш scaleBand
был расширен (расширен), где не хватает данных , Я не думаю, что scaleBand
является правильным способом для этого, но неясно, что это то, что вы хотите. Диапазонные шкалы предназначены для обеспечения равного расстояния для каждого значения данных и наличия всех значений - это порядковый масштаб.
Предполагая, что вы хотите только масштаб группы, чтобы привести в соответствии с вашими данными, где он присутствует:
При входе в домены каждого из й шкал (scaleBand
и scaleLinear
) мы находим, что scaleBand
имеет домен:
[ "1", "2", "8", "9", "13", "14", "20", "22" ] // 8 elements
И в scaleLinear
есть домен:
[ 1, 22 ] // a span of 22 'elements'
scaleBand
будет нуждаться в эквивалентном домене scaleLinear
. Вы можете сделать это статически (что я покажу в основном, чтобы продемонстрировать, как d3.диапазон будет работать):
let xBand = d3.scaleBand()
.domain(d3.range(1,23))
.rangeRound([0, width]);
Это на самом деле производит домен, который имеет 22 элементов с 1 по 22
или динамически:
let xBand = d3.scaleBand()
.domain(d3.range(d3.min(testData1, d => d[0],
d3.max(testData1, d => d[0]+1)))
Вы можете сделать это другими способами, но d3.range()
function is nice and easy.
Однако есть еще одна проблема, которая остается, это выравнивание тиков между двумя шкалами. Для линейной шкалы галочка для первого значения (1) находится на оси y, но шкала зазора зоны запускает (и не центрируется) по оси y и заполняет промежуток между 1 и 2. Другими словами , центральная точка полосы не выравнивается вертикально с вершинами линейного графа.
Эту проблему можно решить путем добавления 0,5 к обеим нижним и верхним пределами области линейной шкалы в:
let xDomain = [
d3.min(testData1, d => d[0]-0.5),
d3.max(testData1, d => d[0]+0.5)
];
Я udpated ваш codepen с соответствующими изменениями: codepen.
И в том случае, что исчезает, вот фрагмент (мышь над не работает для меня почему-то в этом фрагменте, он делает в codepen)
let width = 1000;
let height = 300;
let svg = d3.select(".wrapper-area-simple").append("svg")
.attr("width", width + 80)
.attr("height", height + 80)
.append('svg:g')
.attr('transform', 'translate(40, 30)');
let testData1 = [
[ 1, 10],
[ 2, 30],
[ 8, 34],
[ 9, 26],
[13, 37],
[14, 12],
[20, 23],
[22, 16],
];
let xDomain = [
d3.min(testData1, d => d[0]-0.5),
d3.max(testData1, d => d[0]+0.5)
];
let x = d3.scaleLinear()
.rangeRound([0, width])
.domain(xDomain);
let y = d3.scaleLinear()
.range([height, 0])
.domain(d3.extent(testData1, d => d[1]));
let line = d3.line()
.x(d => x(d[0]))
.y(d => y(d[1]));
svg.append('svg:g')
.datum(testData1)
.append('svg:path')
.attr('d', line)
.attr('fill', 'none')
.attr('stroke', '#000');
let xAxis = d3.axisBottom(x)
.ticks(testData1.length);
svg.append('svg:g')
.call(xAxis)
.attr('transform', `translate(0, 300)`);
let xBand = d3.scaleBand()
.domain(d3.range(d3.min(testData1, d => d[0]),
d3.max(testData1, d => d[0]+1)
))
.rangeRound([0, width]);
svg.append('svg:g')
.selectAll('rect')
.data(testData1)
.enter()
.append('svg:rect')
.attr('x', d => xBand(d[0]))
.attr('width', xBand.bandwidth())
.attr('height', height)
.attr('fill', '#000')
.on('mouseover', function() {
d3.select(this).classed('over', true);
})
.on('mouseout', function() {
d3.select(this).classed('over', false);
});
svg {
border: 1px solid red;
}
rect {
opacity: .1;
}
rect.over {
opacity: .2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"> </script>
<div class="wrapper-area-simple"></div>
Мышь ** работает **, проблема в CSS. Удалите Sass. –
Ах, по телефону сейчас, я буду обновлять завтра, спасибо за подсказку –
Хороший ответ, именно то, что я хотел. Большое спасибо за ответ. – PRAISER