D3js - изменить вертикальную гистограмму на горизонтальную гистограмму
У меня есть вертикальная гистограмма, которая сгруппирована в пары. Я пытался поиграть, как перевернуть его по горизонтали. В моем случае ключевые слова появятся на оси y, а шкала появится на оси x.
Я попытался переключить различные переменные x/y, но это, конечно, только что вызвало фанковые результаты. В каких областях моего кода мне нужно сосредоточиться, чтобы переключить его с вертикальных полос на горизонтальные?
My JSFiddle: Full Code
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, w], 0.05);
// ternary operator to determine if global or local has a larger scale
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function (d) {
return (d.local > d.global) ? d.local : d.global;
})])
.range([h, 0]);
var xAxis = d3.svg.axis()
.scale(xScale)
.tickFormat(function (d) {
return dataset[d].keyword;
})
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5);
var commaFormat = d3.format(',');
//SVG element
var svg = d3.select("#searchVolume")
.append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Graph Bars
var sets = svg.selectAll(".set")
.data(dataset)
.enter()
.append("g")
.attr("class", "set")
.attr("transform", function (d, i) {
return "translate(" + xScale(i) + ",0)";
});
sets.append("rect")
.attr("class", "local")
.attr("width", xScale.rangeBand() / 2)
.attr("y", function (d) {
return yScale(d.local);
})
.attr("x", xScale.rangeBand() / 2)
.attr("height", function (d) {
return h - yScale(d.local);
})
.attr("fill", colors[0][1])
;
sets.append("rect")
.attr("class", "global")
.attr("width", xScale.rangeBand() / 2)
.attr("y", function (d) {
return yScale(d.global);
})
.attr("height", function (d) {
return h - yScale(d.global);
})
.attr("fill", colors[1][1])
;
sets.append("rect")
.attr("class", "global")
.attr("width", xScale.rangeBand() / 2)
.attr("y", function (d) {
return yScale(d.global);
})
.attr("height", function (d) {
return h - yScale(d.global);
})
.attr("fill", colors[1][1])
;
Ответы
Ответ 1
Я просто сделал то же самое вчера вечером, и в основном я переписал код, поскольку он был быстрее, чем исправление всех ошибок, но здесь советы, которые я могу вам дать.
Самые большие проблемы с переворачиванием оси x и y будут с такими вещами, как return h - yScale(d.global)
, потому что высота вычисляется с "вершины" страницы не снизу.
Еще одна важная вещь, которую следует помнить, заключается в том, что при установке .attr("x", ..)
убедитесь, что вы установили ее в 0 (плюс любое дополнение для левой стороны), так = .attr("x", 0)"
Я использовал этот учебник, чтобы помочь мне подумать о моем собственном коде с точки зрения горизонтальных баров вместо этого - он действительно помог
http://hdnrnzk.me/2012/07/04/creating-a-bar-graph-using-d3js/
здесь мой собственный код делает его горизонтальным, если это помогает:
var w = 600;
var h = 600;
var padding = 30;
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d){
return d.values[0]; })]) //note I'm using an array here to grab the value hence the [0]
.range([padding, w - (padding*2)]);
var yScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([padding, h- padding], 0.05);
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", 0 + padding)
.attr("y", function(d, i){
return yScale(i);
})
.attr("width", function(d) {
return xScale(d.values[0]);
})
.attr("height", yScale.rangeBand())
Ответ 2
Альтернативой является поворот диаграммы (см. этот). Это немного взломанно, так как тогда вам нужно поддерживать обведенные оси в голове (высота на самом деле равна ширине и т.д.), Но это, возможно, проще, если у вас уже есть вертикальная диаграмма.
Ниже приведен пример поворота диаграммы. Возможно, вам придется повернуть текст, чтобы сделать его приятным.
_chart.select('g').attr("transform","rotate(90 200 200)");
Ответ 3
Вот процедура, которую я использую в этом случае:
1) Обратное все Xs и Ys
2) Помните, что 0 для y сверху, поэтому вам нужно будет инвертировать множество значений, поскольку предыдущие значения для y будут инвертированы (вы не хотите, чтобы ваша ось x перемещалась слева направо), и новая ось y также будет инвертирована.
3) Убедитесь, что полосы отображаются правильно
4) Адаптировать легенды, если есть проблемы
Этот вопрос может помочь в том смысле, что он показывает, как перейти от горизонтальных гистограмм к вертикали: гистограмма d3.js с положительными и отрицательными значениями
Ответ 4
Еще один интересный горизонтальный график NVD3, который я нашел полезным. Попробуйте.