我正在创建一个字母频率分析网络工具。给定一个句子,它应该计算每个字母在句子中的数量,然后显示该字母在句子中出现次数的百分比。例如“hello”h是20.00% e是20.00% l是40.00% o是20.00%。
但是我在设置y轴标签的格式时遇到了问题。我希望将标签四舍五入为2个小数位,并在末尾添加一个百分比符号。下面列出了我在www.example.com上尝试过的一些方法yAxis.call:
- yAxis.calld3.axisLeft(y).滴答格式(d3.format(“.2f%”)()));//以千为单位给出百分比
- yAxis.calld3.axisLeft(y).滴答格式(d3.format(“.2f”)+“%”));//使轴消失
- yAxis.calld =〉d +“%”));//给出百分比,但不给出小数点空格
我90%肯定问题出在.tickFormat和d3.format上。
const form = document.querySelector("form");
const sentenceInput = document.querySelector("#sentence");
const alphabet = "abcdefghijklmnopqrstuvwxyz".split("");
let letterCounts = {};
let totalCount = 0;
const margin = {top: 30, right: 20, bottom: 30, left: 50};
const width = 600 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
const x = d3.scaleBand().range([0, width]).padding(0.1);
const y = d3.scaleLinear().range([height, 0]);
const svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);
function countLetters(sentence) {
totalCount = 0;
sentence = sentence.toLowerCase();
for (let i = 0; i < sentence.length; i++) {
let letter = sentence[i];
if (letter >= 'a' && letter <= 'z') {
if (letterCounts[letter]) {
letterCounts[letter]++;
} else {
letterCounts[letter] = 1;
}
totalCount++;
}
}
}
let xAxis = svg.append("g").attr("transform", "translate(0," + height + ")");
let yAxis = svg.append("g");
function displayChart() {
svg.selectAll("rect").remove();
var data = alphabet.map(letter => ({letter, frequency: (letterCounts[letter] / totalCount) * 100}));
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, 100]);
var barGroup = svg.append("g");
// append the rectangles for the bar chart
barGroup.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); });
xAxis.call(d3.axisBottom(x));
yAxis.call(d3.axisLeft(y).tickFormat(d3.format(".2f")));
}
form.addEventListener("submit", event => {
totalCount = 0;
event.preventDefault();
let sentence = sentenceInput.value;
letterCounts = {}
countLetters(sentence);
displayChart();
});
.container {
display: flex;
flex-direction: column;
align-items: center;
}
form {
margin: auto;
text-align:center;
}
textarea{
margin:auto;
}
input[type="submit"] {
margin: auto;
}
#chart {
text-align: center;
margin: auto;
width: 80%;
height: 80%;
padding: 20px;
}
rect {
fill: #008080;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Letter Count</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h1>Letter Count</h1>
<div class="container">
<form>
<label for="sentence">Enter a sentence:</label>
<br>
<textarea id="sentence" name="sentence" rows="5" cols="100"></textarea>
<br>
<input type="submit" value="Submit" id="submit-btn">
</form>
</div>
<div id="chart"></div>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="index.js"></script>
</body>
</html>
1条答案
按热度按时间3bygqnnd1#
你的第二个选择几乎是正确的,它的问题在于你传递给函数的数据加上一个字符串(字符串本身就是字符串),这是行不通的。
而是将数据传递给函数,函数返回一个字符串,然后连接另一个字符串(
"%"
):下面是修改后的代码:
x一个一个一个一个x一个一个二个一个x一个一个三个一个