如何在条形图上绘制 x 轴值?

How to plot x axis values over bars?

我更改了 X 轴的属性以在图表的条形图上绘制它的值。但是在我放置代码的任何地方,值总是绘制在条形图之前(“后面”),因此我们看不到它。

  //This part of the code is OUTSIDE of the update function (line 44 of the fiddle)
  //append group to plot X axis
  const xAxisGroup = g.append("g")
    .attr("class", "x axis")
    .attr("transform", `translate(0, ${HEIGHT})`)


  //This part of the code is INSIDE the update function (line 92)
  const xAxisCall = d3.axisBottom(x)
  xAxisGroup.call(xAxisCall)
    .selectAll("text")
    .attr("x", "-5") // <<<--- I change this to 50
    .attr("y", "10")
      .attr("text-anchor", "end")
      .attr("transform", "rotate(-45)") // <<<--- I changed this to -90

如何在条形图上绘制此值?

这是 original chart and this is the modified 的 fiddle。月份值可能落后...... :-/

在 SVG 中,稍后 绘制的任何内容都位于顶部。因此,只需在绘制矩形后附加 x 轴 <g> 元素。或者,提高它:

xAxisGroup.raise()

这是您的代码,其中包含该更改:

//set general margin, width and height values
const MARGIN = {
  LEFT: 128,
  RIGHT: 8,
  TOP: 32,
  BOTTOM: 128
}
const WIDTH = 400 - MARGIN.LEFT - MARGIN.RIGHT
const HEIGHT = 300 - MARGIN.TOP - MARGIN.BOTTOM

//append svg plot area into div chart area
const svg = d3.select("#chart-area").append("svg")
  .attr("width", WIDTH + MARGIN.LEFT + MARGIN.RIGHT)
  .attr("height", HEIGHT + MARGIN.TOP + MARGIN.BOTTOM)

//append group into svg 
const g = svg.append("g")
  .attr("transform", `translate(${MARGIN.LEFT}, ${MARGIN.TOP})`)

//X label
g.append("text")
  .attr("class", "x axis-label")
  .attr("x", WIDTH / 2)
  .attr("y", HEIGHT + 60)
  .attr("font-size", "20px")
  .attr("text-anchor", "middle")
  .text("Month")

//Y label
g.append("text")
  .attr("class", "y axis-label")
  .attr("x", -(HEIGHT / 2))
  .attr("y", -60)
  .attr("font-size", "20px")
  .attr("text-anchor", "middle")
  .attr("transform", "rotate(-90)")
  .text("Value")

//set scale for X axis
const x = d3.scaleBand()
  .range([0, WIDTH])
  .paddingInner(0.3)
  .paddingOuter(0.2)

//set scale for Y axis
const y = d3.scaleLinear()
  .range([HEIGHT, 0])

//append group to plot X axis
const xAxisGroup = g.append("g")
  .attr("class", "x axis")
  .attr("transform", `translate(0, ${HEIGHT})`)

//append group to plot Y axis
const yAxisGroup = g.append("g")
  .attr("class", "y axis")

//import data
d3.csv("https://raw.githubusercontent.com/dbahiense/sotabook/main/revenues.csv").then(data => {
  //parse values
  data.forEach(d => {
    d.revenue = Number(d.revenue)
    d.profit = Number(d.profit)
  })

  //listen drop-down lists and trigger update function on change
  //state
  d3.select("#state")
    .on("change", function(event, d) {
      update(data)
    })
  //round
  d3.select("#round")
    .on("change", function(event, d) {
      update(data)
    })

  //plot chart on page first load
  update(data)
})

// update chart function
function update(data) {
  //drop-down list listened values
  let state = d3.select("#state").property("value")
  let round = d3.select("#round").property("value")

  //filter data by drop-down list values
  let filteredData = data.filter(function(d) {
    return d.state == state & d.round == round
  })

  //set domains for X and Y axes
  x.domain(filteredData.map(d => d.month))
  y.domain([0, d3.max(filteredData, d => d.revenue)])

  const xAxisCall = d3.axisBottom(x)

  const yAxisCall = d3.axisLeft(y)
  //.tickFormat(d => d + "m")
  yAxisGroup.call(yAxisCall)

  // JOIN new data with old elements.
  const rects = g.selectAll("rect")
    .data(filteredData)

  // EXIT old elements not present in new data.
  rects.exit().remove()

  // UPDATE old elements present in new data.
  rects
    .attr("y", d => y(d.revenue))
    .attr("x", (d) => x(d.month))
    .attr("width", x.bandwidth)
    .attr("height", d => HEIGHT - y(d.revenue))

  // ENTER new elements present in new data.  
  rects.enter().append("rect")
    .attr("y", d => y(d.revenue))
    .attr("x", (d) => x(d.month))
    .attr("width", x.bandwidth)
    .attr("height", d => HEIGHT - y(d.revenue))
    .attr("fill", "steelblue")

  xAxisGroup.raise()
    .call(xAxisCall)
    .selectAll("text")
    .attr("x", "50")
    .attr("y", "10")
    .attr("text-anchor", "end")
    .attr("transform", "rotate(-90)")
}
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="description" content="">
    <title>5.4</title>
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <!-- Custom styling -->
    <link rel="stylesheet" href="css/style.css">
</head>
<body>

    <!-- Bootstrap grid setup -->
    <div class="container">
        <div class="row">
            <select id="state">
                <option value="US">US</option>
                <option value="EU">EU</option>
                <option value="AS">AS</option>
            </select>

            <select id="round">
                <option value="1">1</option>
                <option value="2">2</option>
            </select>
        </div>
        <div class="row">
            <div id="chart-area"></div>
        </div>
    </div>

    <!-- External JS libraries -->
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    <!-- Custom JS below-->
</body>
</html>