javascript 如何将y轴标签四舍五入到2个小数位,并在末尾连接百分比符号?

sxissh06  于 2023-01-29  发布在  Java
关注(0)|答案(1)|浏览(104)

我正在创建一个字母频率分析网络工具。给定一个句子,它应该计算每个字母在句子中的数量,然后显示该字母在句子中出现次数的百分比。例如“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>
3bygqnnd

3bygqnnd1#

你的第二个选择几乎是正确的,它的问题在于你传递给函数的数据加上一个字符串(字符串本身就是字符串),这是行不通的。
而是将数据传递给函数,函数返回一个字符串,然后连接另一个字符串("%"):

yAxis.call(d3.axisLeft(y).tickFormat(d => d3.format(".2f")(d) + "%"))

下面是修改后的代码:
x一个一个一个一个x一个一个二个一个x一个一个三个一个

相关问题