最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - D3 - yAxis Ticks Not Showing Up - Stack Overflow

programmeradmin5浏览0评论

I'm doing the basic bar graph tutorial for D3, but the ticks for the yAxis aren't showing up even though the line does. This question has been asked a lot, but I still haven't found an answer for my specific situation. Here's my code:

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.axis text {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000000;
}

.x.axis path {
  display: none;
}

.chart rect {
  fill: steelblue;
}

.chart text {
  fill: white;
  font: 10px sans-serif;
  text-anchor: end;
}

</style>

<svg class="chart"></svg>

<script src=".v4.min.js" charset="utf-8"></script>
<script src=".v1.min.js"></script>
<script src=".v1.min.js"></script>
<script src=".v1.min.js"></script>
<script src=".v1.min.js"></script>
<script src=".v1.min.js"></script>
<script src=".v1.min.js"></script>
<script src=".v2.min.js"></script>
<script src=".v1.min.js"></script>

<script>

var data = [4, 8, 15, 16, 23, 42];
var width = 960, height = 500
var barWidth = width / data.length

var yScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d)])
  .range([height, 0])

var chart = d3.select(".chart")
  .attr('width', width)
  .attr('height', height)

chart.append("g")
  .attr("class", "y axis")
  .call(d3.axisLeft(yScale));

var groups = chart.selectAll(".bar")
    .data(data)
  .enter().append("g")
    .attr('transform', (d, i) => `translate(${i * barWidth}, 0)`)

groups.append('rect')
  .attr('y', (d) => yScale(d))
  .attr('height', (d) => height - yScale(d))
  .attr('width', barWidth - 1)

groups.append('text')
  .attr('x', barWidth / 2)
  .attr('height', (d) => height - yScale(d))
  .attr('width', barWidth - 1)
  .text(d => d)

</script>

Fun fact: when I append the axis using axisBottom instead of axisLeft, I can see the axis with its ticks (obviously not oriented correctly). Thanks for the help in advance!

I'm doing the basic bar graph tutorial for D3, but the ticks for the yAxis aren't showing up even though the line does. This question has been asked a lot, but I still haven't found an answer for my specific situation. Here's my code:

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.axis text {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000000;
}

.x.axis path {
  display: none;
}

.chart rect {
  fill: steelblue;
}

.chart text {
  fill: white;
  font: 10px sans-serif;
  text-anchor: end;
}

</style>

<svg class="chart"></svg>

<script src="https://d3js/d3.v4.min.js" charset="utf-8"></script>
<script src="https://d3js/d3-array.v1.min.js"></script>
<script src="https://d3js/d3-collection.v1.min.js"></script>
<script src="https://d3js/d3-color.v1.min.js"></script>
<script src="https://d3js/d3-format.v1.min.js"></script>
<script src="https://d3js/d3-interpolate.v1.min.js"></script>
<script src="https://d3js/d3-time.v1.min.js"></script>
<script src="https://d3js/d3-time-format.v2.min.js"></script>
<script src="https://d3js/d3-scale.v1.min.js"></script>

<script>

var data = [4, 8, 15, 16, 23, 42];
var width = 960, height = 500
var barWidth = width / data.length

var yScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d)])
  .range([height, 0])

var chart = d3.select(".chart")
  .attr('width', width)
  .attr('height', height)

chart.append("g")
  .attr("class", "y axis")
  .call(d3.axisLeft(yScale));

var groups = chart.selectAll(".bar")
    .data(data)
  .enter().append("g")
    .attr('transform', (d, i) => `translate(${i * barWidth}, 0)`)

groups.append('rect')
  .attr('y', (d) => yScale(d))
  .attr('height', (d) => height - yScale(d))
  .attr('width', barWidth - 1)

groups.append('text')
  .attr('x', barWidth / 2)
  .attr('height', (d) => height - yScale(d))
  .attr('width', barWidth - 1)
  .text(d => d)

</script>

Fun fact: when I append the axis using axisBottom instead of axisLeft, I can see the axis with its ticks (obviously not oriented correctly). Thanks for the help in advance!

Share Improve this question asked Nov 22, 2016 at 23:25 LeeLee 591 silver badge4 bronze badges 1
  • Add a fiddle to be able to solve it quickly – spooky Commented Nov 22, 2016 at 23:28
Add a ment  | 

3 Answers 3

Reset to default 5

The problem here is that the axis generator creates an axis which, when called (using call), is painted at the 0,0 position:

Regardless of orientation, axes are always rendered at the origin.

So, you need to translate the axis, moving it a little bit to the right:

chart.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(30,0)")//magic number, change it at will
    .call(d3.axisLeft(yScale));

Here is the demo:

<style>

.axis text {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000000;
}

.x.axis path {
  display: none;
}

.chart rect {
  fill: steelblue;
}

.barText {
  fill: white;
  font: 10px sans-serif;
  text-anchor: end;
}

</style>

<svg class="chart"></svg>

<script src="https://d3js/d3.v4.min.js" charset="utf-8"></script>
<script src="https://d3js/d3-array.v1.min.js"></script>
<script src="https://d3js/d3-collection.v1.min.js"></script>
<script src="https://d3js/d3-color.v1.min.js"></script>
<script src="https://d3js/d3-format.v1.min.js"></script>
<script src="https://d3js/d3-interpolate.v1.min.js"></script>
<script src="https://d3js/d3-time.v1.min.js"></script>
<script src="https://d3js/d3-time-format.v2.min.js"></script>
<script src="https://d3js/d3-scale.v1.min.js"></script>

<script>

var data = [4, 8, 15, 16, 23, 42];
var width = 500, height = 300
var barWidth = width / data.length

var yScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d)])
  .range([height - 10, 0])

var chart = d3.select(".chart")
  .attr('width', width)
  .attr('height', height)

var groups = chart.selectAll(".bar")
    .data(data)
  .enter().append("g")
    .attr('transform', (d, i) => `translate(${i * barWidth + 30}, 0)`)

groups.append('rect')
  .attr('y', (d) => yScale(d))
  .attr('height', (d) => height - 10 - yScale(d))
  .attr('width', barWidth - 1)

groups.append('text')
	.attr("class", "barText")
  .attr('x', barWidth / 2)
	.attr('y', d=> yScale(d) + 16)
  .attr('height', (d) => height - 10 - yScale(d))
  .attr('width', barWidth - 1)
  .text(d => d)
	
	chart.append("g")
  .attr("class", "y axis")
	.attr("transform", "translate(30,0)")
  .call(d3.axisLeft(yScale));

</script>

PS: You have some additional issues in your code, that you can improve (here, I'm simply answering your question):

  1. Your code lacks all the paddings (left, right, top, bottom);
  2. You should use a scale for x positioning
  3. You don't need to calculate the bar width, bandwidth() does that automatically.
  4. Template literals don't work on IE

I not an expert but I think I figured it out. You were not assiging approriate x,y for your .text()... I have modified code that works for me... See the JS fiddle:

https://jsfiddle/wpfkm6dn/2/

code is below:

    <!DOCTYPE html>
<meta charset="utf-8">
<style>

.axis text {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000000;
}

.x.axis path {
  display: none;
}

.chart rect {
  fill: steelblue;
}

.chart text {
  fill: white;
  font: 10px sans-serif;
  text-anchor: end;
}

</style>

<svg class="chart"></svg>

<script src="https://d3js/d3.v4.min.js" charset="utf-8"></script>
<script src="https://d3js/d3-array.v1.min.js"></script>
<script src="https://d3js/d3-collection.v1.min.js"></script>
<script src="https://d3js/d3-color.v1.min.js"></script>
<script src="https://d3js/d3-format.v1.min.js"></script>
<script src="https://d3js/d3-interpolate.v1.min.js"></script>
<script src="https://d3js/d3-time.v1.min.js"></script>
<script src="https://d3js/d3-time-format.v2.min.js"></script>
<script src="https://d3js/d3-scale.v1.min.js"></script>

<script>

var data = [4, 8, 15, 16, 23, 42];
var width = 960, height = 500
var barWidth = width / data.length

var yScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d)])
  .range([height, 0])

var chart = d3.select(".chart")
  .attr('width', width)
  .attr('height', height)

chart.append("g")
  .attr("class", "y axis")
  .call(d3.axisLeft(yScale));

var groups = chart.selectAll(".bar")
    .data(data)
  .enter().append("g")
    .attr('transform', (d, i) => `translate(${i * barWidth}, 0)`)

groups.append('rect')
  .attr('y', (d) => yScale(d))
  .attr('height', (d) => height - yScale(d))
  .attr('width', barWidth - 1)

groups.append('text')
  .attr('y', (d) => yScale(d) + 20)
  .attr('x', barWidth / 2)
  .attr('height', (d) => height - yScale(d))
  .attr('width', barWidth - 1)
  .text(d => d)

</script>

Not sure if you've solved it yet but I've taken another approach. fiddle

var data = [4, 8, 15, 16, 23, 42];

var svg = d3.select(".chart");
// we need to set a margin so that the yAxis has space to display
var margin = {top: 20, right: 20, bottom: 30, left: 40};
// these variables are assigned such that the margin is already deducted
var width = +svg.attr("width") - margin.left - margin.right;
var height = +svg.attr("height") - margin.top - margin.bottom;

var padding = 5; //5 px padding between bars
var barWidth = width / data.length - padding;

var yScale = d3.scaleLinear()
  .domain([0, d3.max(data)]) // here we can just call d3.max(data) because data is an array
  .range([height, 0]);

var g = svg.append('g')
  .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

g.append('g')
  .attr('class', 'axis axis--y')
  .call(d3.axisLeft(yScale).ticks(5));

g.selectAll('.bar')
  .data(data)
  .enter().append('rect')
  .attr('class', 'bar')
  .attr('x', function(d, i) { return (barWidth + padding) * i; })
  .attr('y', function(d) { return yScale(d); })
  .attr('width', barWidth)
  .attr('height', function(d) { return height - yScale(d); });

Based off of https://bl.ocks/mbostock/3885304

发布评论

评论列表(0)

  1. 暂无评论