#javascript #css #d3.js #svg
#javascript #css #d3.js #svg
Вопрос:
У меня есть гистограмма, где я хотел бы добавить круглый красный крестик в правом верхнем углу каждой строки, чтобы показать, что пользователь может удалить определенную строку, но у меня возникли проблемы с выяснением, как это добавить. Мне нравится, чтобы конечное изображение было таким, но также повторялось и на других четырех столбцах.
Я предоставил jsfiddle вместе с JS-кодом, который выполняет все остальное, что мне нравится в графике, за исключением отсутствия красного x.
// graph variables
var xScale ,
yScale ,
xAxis ,
yAxis ;
// chart dimensions
var margin = { top: 20, right: 30, bottom: 20, left: 70 },
width = $('#chart').width() - margin.left - margin.right,
height = $(window).height() / 3.5 - margin.top - margin.bottom;
// color palette for graph
var colors = [ '#4398B5', '#ADC4CC', '#92B06A', '#E09D2A', '#DE5F32' ];
var data = [
{ id : 1, value : 100},
{ id : 2, value : 200},
{ id : 3, value : 300},
{ id : 4, value : 400},
{ id : 5, value : 500}
];
// svg object for graph
var svg;
xScale = d3.scaleBand()
.domain( d3.range( data.length ) )
.range( [ 0, width ] )
.padding( 0.1 );
var yMax = d3.max( data, function( d ) {
return d.value;
});
yScale = d3.scaleLinear()
.domain( [ 0, yMax ] )
.range( [ height, 0 ] );
xAxis = d3.axisBottom( xScale );
yAxis = d3.axisLeft( yScale );
var yTicks = yAxis.ticks(5),
yTicksFormat = yAxis.tickFormat( d3.format( '$,' ) );
svg = d3.select( '#chart svg' )
.attr('viewBox', '0 0 ' ( width margin.left margin.right ) ' ' ( height margin.top margin.bottom ) )
.attr('height', ( height 'px' ) )
.attr('width', '100%')
.attr('preserveAspectRatio', 'none')
.append( 'g' )
.attr( 'transform', 'translate(' margin.left ',' margin.top ')' );
svg.selectAll( 'rect' )
.data( data )
.enter()
.append( 'rect' )
.attr('x', function ( d, i ) {
return xScale( i );
})
.attr('y', function( d, i ) {
return yScale( 0 );
})
.attr( 'height', function( d ) {
return height - yScale( 0 );
})
.attr( 'width', xScale.bandwidth() )
.attr('fill', function( d, i ) {
return colors[ i ];
})
.transition()
.duration( 1500 )
.attr( 'y', function( d, i ) {
return yScale( d.value );
})
.attr( 'height', function( d ) {
return height - yScale( d.value );
})
.on('end', function( d, i ) {
/*Insert this button somewhere
<button type="button" class="btn btn-default btn-circle btn-danger"><i class="glyphicon glyphicon-remove"></i></button>*/
});
svg.append( 'g' )
.attr( 'class', 'yAxis' )
.attr( 'transform', 'translate(0, ' (-1) ')')
.call( yAxis );
Я бы предположил, что нужно вставить красный крестик после вызова каждой .on('end', function...)
функции bars.
Сам по себе красный x будет
<button type="button" class="btn btn-default btn-circle btn-danger"><i class="glyphicon glyphicon-remove"></i></button>*/
И CSS для этого будет
.btn-circle {
width: 19px;
height: 19px;
text-align: center;
padding: 1px 0;
font-size: 13px;
line-height: 0.1;
border-radius: 30px;
}
который предоставляется в JSFiddle. Любая помощь будет с благодарностью принята.
Спасибо!
Комментарии:
1. вам нужно, чтобы X рос вместе с столбцами? или просто появится в конце анимации?
2. Извините, если вы упомянули, что я думаю, что все в порядке, если значок остается того же размера, пока он отображается в правом верхнем углу. На случай, если я захочу, чтобы он рос, я думаю, я мог бы поместить его в адаптивный div, и все будет в порядке, но я не уверен.
3. Я имел в виду — вам нужно их анимировать — поднимать с помощью баров, появляться в конце загрузки SVG или просто быть там постоянно?
4. О, моя ошибка, да, мне нравится, чтобы они начинались снизу, если это возможно, и поднимались вместе с баром.
5. Хм, этот SVG меняет размер в зависимости от высоты окна. Разве это не будет фиксированный размер?
Ответ №1:
Вместо добавления a div
(или любого другого элемента HTML, который вы не можете добавить в SVG), проще добавить элемент круга SVG и текстовый элемент SVG, имитирующий кнопку:
var circles = svg.selectAll('.circles')
.data(data)
.enter()
.append('circle').attr("cursor", "pointer")
.attr('cx', function (d, i) {
return xScale(i) xScale.bandwidth();
})
.attr('cy', function(d, i) {
return yScale(0);
})
.attr('fill', "red").attr("r", 8)
.transition()
.duration(1500)
.attr('cy', function(d, i) {
return yScale( d.value );
});
var xtext = svg.selectAll('.xtext')
.data(data)
.enter()
.append('text')
.attr('x', function (d, i) {
return xScale( i ) xScale.bandwidth();
})
.attr('y', function( d, i ) {
return yScale( 0 );
})
.attr('fill', "white")
.attr("text-anchor", "middle")
.attr("dominant-baseline", "central")
.attr("pointer-events", "none")
.text("x")
.transition()
.duration( 1500 )
.attr( 'y', function( d, i ) {
return yScale( d.value );
});
Вот скрипка: https://jsfiddle.net/dcb8ok9j /
PS: это добавляет только круги, вам нужно будет добавить поведение отдельно.