Я хочу создать гистограмму следующим образом:
Есть два столбца графика один под другим, первый растет вверх, а второй - вниз.
У них разные масштабы и данные.
Это то, что я создал:
var doublebarSvg1 = d3.select('#doublebar')
.append('svg')
.attr('class', 'doublebarSvg1')
.attr('width', 700)
.attr('height', 400);
var doublebarSvg2 = d3.select('#doublebar')
.append('svg')
.attr('class', 'doublebarSvg2')
.attr('width', 700)
.attr('height', 400);
var margin = {top: 0, right: 0, bottom: 0, left: 50};
var width = doublebarSvg1.attr('width') - margin.left - margin.right;
var height = doublebarSvg1.attr('height') - margin.top - margin.bottom;
var x = d3.scaleBand()
.rangeRound([0, width])
.padding(0.1)
.domain(years);
var y1 = d3.scaleLinear()
.rangeRound([height, 0])
.domain([0, 100]);
var y2 = d3.scaleSqrt()
.rangeRound([height, 0])
.domain([813, 0.1]); // max value 812.05 but domain is [0, 100000]
var doublebarSvgG1 = doublebarSvg1.append('g').attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
var doublebarSvgG2 = doublebarSvg2.append('g').attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
////////////////////////////////////////////////////////////////////////
// Tooltip.
////////////////////////////////////////////////////////////////////////
var svgTip = doublebarSvg1.append('svg').attr('id', 'tooltip');
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-5, 0])
.html(function(d) {
return '<div><span>Country:</span> <span style=\'color:white\'>' + d.country + '</span></div>' +
'<div><span>Perc:</span> <span style=\'color:white\'>' + d.perc + '%</span></div>' +
'<div><span>Rate:</span> <span style=\'color:white\'>' + d.rate + '%</span></div>';
});
svgTip.call(tip);
////////////////////////////////////////////////////////////////////////
// Draw a single double bar
////////////////////////////////////////////////////////////////////////
makeDoublebar1();
function makeDoublebar1() {
// define the axes
var xAxis = d3.axisBottom(x);
var yAxis1 = d3.axisLeft(y1);
// create x axis
doublebarSvgG1.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0, ' + height + ')')
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.attr('transform', 'rotate(-65)');
// create y axis
doublebarSvgG1.append('g')
.attr('class', 'y axis')
.call(yAxis1)
.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 6)
.attr('dy', '.71em')
.style('text-anchor', 'end');
// create bar rect
doublebarSvgG1.selectAll('.bar')
.data(testData1) //.data(covFiltered)
.enter().append('rect')
.attr('fill', 'steelblue')
.attr('class', 'bar')
.attr('x', function(d) {
return x(d.year);
})
.attr('y', function(d) {
if(isNaN(d.perc)) {
d.perc = 0;
}
return y1(d.perc);
})
.attr('width', x.bandwidth())
.attr('height', function(d) {
if(isNaN(d.perc)) {
d.perc = 0;
}
return height - y1(d.perc);
})
.on('mouseover', function(d) {
d3.select(this).attr('fill', 'darkblue');
tip.show(d);
})
.on('mouseout', function(d) {
d3.select(this).attr('fill', 'steelblue');
tip.hide(d);
});
}
////////////////////////////////////////////////////////////////////////
// Draw a single double bar
////////////////////////////////////////////////////////////////////////
makeDoublebar2();
function makeDoublebar2() {
// define the axes
var xAxis = d3.axisBottom(x);
var yAxis2 = d3.axisLeft(y2);
// create x axis
doublebarSvgG2.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0, 0)')
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.attr('transform', 'rotate(-65)');
// create y axis
doublebarSvgG2.append('g')
.attr('class', 'y axis')
.call(yAxis2)
.append('text')
.style('text-anchor', 'end');
// create bar rect
doublebarSvgG2.selectAll('.bar')
.data(testData2)
.enter().append('rect')
.attr('fill', 'tomato')
.attr('class', 'bar')
.attr('x', function(d) { // left start point
return x(d.year);
})
.attr('y', function(d) { // top start point
if(isNaN(d.rate)) {
d.rate = 0;
}
return 0;
})
.attr('width', x.bandwidth())
.attr('height', function(d) {
if(isNaN(d.rate)) {
d.perc = 0;
}
return y2(d.rate);
})
.on('mouseover', function(d) {
d3.select(this).attr('fill', 'red');
tip.show(d);
})
.on('mouseout', function(d) {
d3.select(this).attr('fill', 'tomato');
tip.hide(d);
});
}
PLUNKER здесь .
Есть некоторые проблемы:
если я заменим .axis {display: initial;}
на .axis {display: none;}
, все оси исчезнут, но я хочу горизонтальную линию между двумя диаграммами
Мне бы хотелось, чтобы была только одна подсказка, которая, когда пользователь наводит курсор на любую полосу, выходит с подсказкой, которая показывает значения perc
и rate
.
И, что более важно, это самый умный способ создать такую диаграмму?