d3.Масштабная полоса() и d3.Линейная шкала (), действующие неожиданно

#javascript #html #d3.js

Вопрос:

 .main{
} 
 <!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/styles.css">
<title>Compounding Gains Calculator</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var calculated = false;
var ifChanged = false;

  //comment

function changedNumInput(event) {
  ifChanged = true;
  calculateProfit();
}

function changeColor() {
  if (ifChanged == true) {
    let x = event.target;
    x.style.color = 'white';
    x.style.transition = 'all ease-in-out 0.2s';
  }
}

function clickedButton() {
  calculateProfit();
  alert(rornum);
}


function calculateProfit() {
  var balance = document.getElementsByName("balance")[0].value;
  var monthly = document.getElementsByName("monthly")[0].value;
  var nummonths = document.getElementsByName("nummonths")[0].value;
  var nummonthsList = [];
  for (let i = 0; i <= nummonths; i  ) {
    nummonthsList.push(i.toString());
  }
  var ror = document.getElementsByName("ror")[0].value;
  var profit_calculation = [];
  let profit_calculation_nointerest = [];
  var endbalance;
  profit_calculation.push(balance);
  for (let i = 0; i < nummonths; i  ) {
    let num =  monthly;
    var rornum =  ror;
    var percent = (rornum / 100)   1;
    let temp = (profit_calculation[profit_calculation.length - 1] * percent)   num;
    profit_calculation.push(temp.toFixed(2));
  }
  endbalance = profit_calculation[profit_calculation.length - 1];
  let temp = 'Your balance at the end of'
  document.getElementById('balancetext').innerHTML = "Your balance at the end of "   nummonths   " months is <span id='balancevalue'>"   endbalance   "</span>";
  drawGraph(endbalance, nummonthsList, profit_calculation);
}

function drawGraph(endbalance, nummonths, profit_calculation) {

  const DUMMY_DATA = [
    {month: 0, value: 100, nocontribution: 100},
    {month: 1, value: 125, nocontribution: 120},
    {month: 2, value: 150, nocontribution: 140},
    {month: 3, value: 200, nocontribution: 180},
    {month: 4, value: 400, nocontribution: 350},
    {month: 5, value: 900, nocontribution: 600}
  ];


  var margin = {top: 0, right: 20, bottom: 30, left:30};
  var width = 600 - margin.left - margin.right,
        height = 600 - margin.top - margin.bottom;


  const chart = d3
  .select('.main')
  .append('svg');

    chart.attr('width', width   margin.left   margin.right);
    chart.attr('height', height   margin.top   margin.bottom);
    chart.style('margin-left','20%')
    chart.style('margin-top','10%')
    chart.style('grid-area','main');
    chart.style('background-color','#312244');
    chart.style('border','1px solid lightblue');

    var background = chart
    .append('rect');

    background.style('fill','#161616')
    background.attr('width',width)
    background.attr('height',height - margin.bottom)
    background.attr('x',margin.left)
    background.attr('y',margin.top   margin.bottom);

    var y = d3.scaleLinear()
    .domain([0,endbalance * 1.1])
    .range([height - (margin.top   margin.bottom) , 0]);

    var x = d3.scaleBand()
    .domain(nummonths)
    .range([0,width])
    .paddingInner(0.05);

    var xAxisGenerator = d3.axisBottom(x)
    .ticks(nummonths)
    .tickSize(- height   margin.top   margin.bottom);

    var yAxisGenerator = d3.axisLeft(y)
    .ticks(10)
    .tickSize(- width);

    let xAxis = chart.append('g')
        .attr("transform", "translate("   margin.left   ","   height   ")")
        .attr('class', 'x_axis')
        .call(xAxisGenerator);

    let yAxis = chart.append('g')
        .attr("transform", "translate("   margin.left   ","   (margin.top   margin.bottom)   ")")
        .attr('class', 'y_axis')
        .call(yAxisGenerator);

    xTicks = xAxis.selectAll('.tick');
    yTicks = yAxis.selectAll('.tick');

    xTicks
    .selectAll('text')
    .style('color','white');

    xTicks
    .selectAll('line')
    .attr('stroke','darkgrey')
    .attr('stroke-dasharray','5');

    yTicks
    .selectAll('line')
    .attr('stroke','darkgrey')
    .attr('stroke-dasharray','5');

    yAxis.selectAll('.tick')
    .selectAll('text')
    .style('color','white');

    yAxis.select('.tick')
    .select('line')
    .attr('stroke','black');

    var bars = chart
    .selectAll('bar')
    .data(profit_calculation)
    .enter()
    .append('rect')
    .classed('.bar', true);

    bars.style('fill','lightgreen')
    bars.style('stroke','green')
    bars.style('opacity','0.7')
    bars.attr('width',x.bandwidth()/2)
    bars.attr('height',(data) => height - y(data));
    bars.attr('x',function(d,i) {
      return x(i)   ((margin.left   margin.right) /1.3)
    })
    bars.attr('y', data => y(data));

    alert(profit_calculation);
}
</script>
</head>


<body onload="calculateProfit()">

  <div class="container">
    <div class="side"></div>

      <div class="sidebar">
        <form id="sidebarCentered">
          <div class="siderow">
            <label for="balance" id="focusid">Balance</label>
            <input type="number" name="balance" value=500 autofocus oninput="changedNumInput(event)" onblur="changeColor()">
          </div>
          <div class="siderow">
              <label for="monthly">Monthly contribution</label>
              <input type="number" name="monthly" value=0 oninput="changedNumInput(event)" onblur="changeColor()">
          </div>
          <div class="siderow">
            <label for="nummonths">Number of Months</label>
            <input type="number" name="nummonths" value=12 oninput="changedNumInput(event)" onblur="changeColor()">
          </div>
          <div class="siderow" style="border-bottom:1px solid #3E1F47;">
            <label for="ror">Monthly Rate of Return</label>
            <input type="number" name="ror" value=1 oninput="changedNumInput(event)" onblur="changeColor()">
          </div>
          <div class="sidebarbuttons">
            <input type="button" value="Calculate" onclick="clickedButton()">
          </div>
        </form>
      </div>

    <div class="topbar">

      <div class="menu">
        <div id="centermenu">
          <a href="index.htm">Graph</a>
          <a href="calculator.html" class="active">Calculator</a>
          <a href="layoutTest.html">test</a>
        </div>
      </div>
    </div>

    <div class="main">
      <h1 id ='balancetext'> Your balance at the end of x months is <span id='balancevalue'>y</span></h1>

    </div>





<!-- <canvas id="gainsgraph" height: '100%' width: '100%'>

</canvas> -->


</div>

</body>



</html> 

Привет, я новичок в обучении d3.js и пытались составить простую гистограмму. Я использую d3.scaleBand для оси x и d3.scaleLinear() для оси y. Однако до сих пор столбики отображались намного больше, чем их значение должно быть на оси y, и столбики не центрированы по оси, отмеченной галочками на оси x. Как я мог бы центрировать стержни по оси x и сделать высоту точной по значению?

 function drawGraph() {

  const DUMMY_DATA = [
    {month: 0, value: 100, nocontribution: 100},
    {month: 1, value: 125, nocontribution: 120},
    {month: 2, value: 150, nocontribution: 140},
    {month: 3, value: 200, nocontribution: 180},
    {month: 4, value: 400, nocontribution: 350},
    {month: 5, value: 900, nocontribution: 600}
  ];


  var margin = {top: 0, right: 20, bottom: 30, left:30};
  var width = 600 - margin.left - margin.right,
        height = 600 - margin.top - margin.bottom;


  const chart = d3
  .select('.main')
  .append('svg');

    chart.attr('width', width   margin.left   margin.right);
    chart.attr('height', height   margin.top   margin.bottom);
    chart.style('margin-left','20%')
    chart.style('margin-top','10%')
    chart.style('grid-area','main');
    chart.style('background-color','#312244');
    chart.style('border','1px solid lightblue');

    var background = chart
    .append('rect');

    background.style('fill','#161616')
    background.attr('width',width)
    background.attr('height',height - margin.bottom)
    background.attr('x',margin.left)
    background.attr('y',margin.top   margin.bottom);

    var y = d3.scaleLinear()
    .domain([0,endbalance * 1.1])
    .range([height - (margin.top   margin.bottom) , 0]);

    var x = d3.scaleBand()
    .domain(nummonths)
    .range([0,width])
    .paddingInner(0.05);

    var xAxisGenerator = d3.axisBottom(x)
    .ticks(nummonths)
    .tickSize(- height   margin.top   margin.bottom);

    var yAxisGenerator = d3.axisLeft(y)
    .ticks(10)
    .tickSize(- width);

    let xAxis = chart.append('g')
        .attr("transform", "translate("   margin.left   ","   height   ")")
        .attr('class', 'x_axis')
        .call(xAxisGenerator);

    let yAxis = chart.append('g')
        .attr("transform", "translate("   margin.left   ","   (margin.top   margin.bottom)   ")")
        .attr('class', 'y_axis')
        .call(yAxisGenerator);

    xTicks = xAxis.selectAll('.tick');
    yTicks = yAxis.selectAll('.tick');

    xTicks
    .selectAll('text')
    .style('color','white');

    xTicks
    .selectAll('line')
    .attr('stroke','darkgrey')
    .attr('stroke-dasharray','5');

    yTicks
    .selectAll('line')
    .attr('stroke','darkgrey')
    .attr('stroke-dasharray','5');

    yAxis.selectAll('.tick')
    .selectAll('text')
    .style('color','white');

    yAxis.select('.tick')
    .select('line')
    .attr('stroke','black');

    var bars = chart
    .selectAll('bar')
    .data(profit_calculation)
    .enter()
    .append('rect')
    .classed('.bar', true);

    bars.style('fill','lightgreen')
    bars.style('stroke','green')
    bars.style('opacity','0.7')
    bars.attr('width',x.bandwidth()/2)
    bars.attr('height',(data) => height - y(data));
    bars.attr('x',function(d,i) {
      return x(i)   ((margin.left   margin.right) /1.3)
    })
    bars.attr('y', data => y(data)); 
 <head>
<script>
drawGraph();
</script>
</head>

<body>
</body