javascript - D3 将条形图值旋转 90 度
问题描述
我对 Java Script 和 D3 完全陌生。我正在尝试将条形图中的值旋转 90 度。但是,我不能单独旋转它们。我尝试了许多不同的方法来解决这个问题,但都没有运气。下面是代码。
const render = data => {
const chartTitle = 'Top 10 Most Populous Countries';
const yAxisLabel = 'Population';
const xAxisLabel = 'Country';
const margin = {
top: 100,
right: 50,
bottom: 150,
left: 150
};
// Dimensions: 400 x 400
// used for the initial rendering
// width to height proportion
// its preserved as the chart is resized
const width = 1200 - margin.left - margin.right;
const height = 600 - margin.top - margin.bottom;
console.log(width);
console.log(height);
const xValues = d => d.country;
const yValues = d => d.population;
const yScaleMaxValue = Math.ceil((d3.max(data, yValues)));
console.log(yScaleMaxValue);
const yScaleMinValue = Math.ceil((d3.min(data, yValues)));
console.log(yScaleMinValue);
const xScale = d3.scaleBand().
paddingInner(0.2).
domain(data.map(xValues)).
range([0, width]);
const xAxis = d3.axisBottom(xScale);
const yScale = d3.scaleLinear()
.domain([0, yScaleMaxValue])
.range([height, 0])
;
const yAxisTickFormat = number => d3.format('.3s')(number)
.replace('G','B')
.replace('0.00','0');
const yAxis = d3.axisLeft(yScale).tickFormat(yAxisTickFormat);
const yValuesTextFormat = number => d3.format('.3s')(number);
const svg = d3.select('#responsivechart3').
append('svg').
attr('width', width + margin.left + margin.right).
attr('height', height + margin.top + margin.bottom).
call(responsivefy) // Call responsivefy to make the chart responsive
.append('g').
attr('transform', `translate(${margin.left}, ${margin.top})`);
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('class', 'rect')
.attr('x', d => xScale(xValues(d)))
.attr('y', d => yScale(yValues(d)))
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(yValues(d)))
;
svg.selectAll('text')
.data(data)
.enter()
.append('text')
.attr('class', 'bar-value')
.attr('x', d => xScale(xValues(d)))
.attr('y', d => yScale(yValues(d)))
.text(yValues)
.attr('transform', `rotate(-45)`);
svg.append('g').
call(yAxis);
svg.append('g')
.attr('transform', `translate(0, ${height})`)
.call(xAxis)
.selectAll('text')
.call(wrap, xScale.bandwidth());
svg.append('text')
.attr('class','chart-title')
.attr('y',-50)
.attr('x',100)
.attr('fill', 'black')
.text(chartTitle);
svg.append('text')
.attr('class','axis-label')
.attr('y',450)
.attr('x',400)
.attr('fill', 'black')
.text(xAxisLabel);
svg.append('text')
.attr('class','axis-label')
.attr('y',-100)
.attr('x',-250)
.attr('fill', 'black')
.text(yAxisLabel)
.attr('transform', `rotate(-90)`);
function responsivefy(svg) {
// Container is the DOM element, svg is appended.
// Then we measure the container and find its
// aspect ratio.
const container = d3.select(svg.node().parentNode),
width = parseInt(svg.style('width'), 10),
height = parseInt(svg.style('height'), 10),
aspect = width / height;
// Add viewBox attribute to set the value to initial size
// add preserveAspectRatio attribute to specify how to scale
// and call resize so that svg resizes on page load
svg.attr('viewBox', `0 0 ${width} ${height}`).
attr('preserveAspectRatio', 'xMinYMid').
call(resize);
d3.select(window).on('resize.' + container.attr('id'), resize);
function resize() {
const targetWidth = parseInt(container.style('width'));
svg.attr('width', targetWidth);
svg.attr('height', Math.round(targetWidth / aspect));
}
}
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width+25) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text
.append("tspan")
.attr("x", 0)
.attr("y", y)
.attr("dy", ++lineNumber * lineHeight + dy + "em")
.text(word);
}
}
});
}
};
data = d3.csv('data.csv').then(data => {
data.forEach(d => {
d.population = +d.population * 1000;
});
console.log(data);
render(data);
});
对此的任何帮助将不胜感激。
我还附上了一张图片。
解决方案
推荐阅读
- sql - 有什么方法可以加快 PostgreSQL 中的“foo%”查询?
- python - 在 Python Dash 应用程序中对齐第一列和第二列的高度
- python - 从数据框中获取列中唯一值的最后一行 - Pandas
- swift - 将 Codable 数据转换为 `[String: CustomStringConvertible]` 字典
- powershell - 更改多个目录中 .ini 文件的值
- r - 添加新列并计算从开始到结束的行驶长度
- knockout.js - 淘汰赛 js,针对自定义数组的每个循环问题
- javascript - 在循环中跳过单元格,并调整函数以移动范围
- asp.net-core - ASP.NET 核心 3.1。如果 tha DB 中的特定标志设置为 true,我正在尝试制作一个强制用户更改密码的 Web 应用程序
- javascript - 如何在 json 数组对象中添加 HTML 标签