Tyler Smith
Tyler Smith

Reputation: 53

tickSizeOuter not equal zero, but just first and last tick of yAxis shows line

I have a line chart. And just the first and last tick of yAxis shows the outer line.

The result as below image:

image

The expected result is that every tick of yAxis shows outer line.

Example: https://bl.ocks.org/d3noob/c506ac45617cf9ed39337f99f8511218

And here is my reproduce code:

var margin = { top: 70, right: 30, bottom: 50, left: 40 }
var width = 720 - margin.left - margin.right
var height = 430 - margin.top - margin.bottom

var data = [
   {angle:0.6933744221879815,x:0.1},
   {angle:0.6933744221879815,x:0.1},
   {angle:0.6933744221879815,x:0.3},
   {angle:0.6933744221879815,x:0.4},
   {angle:0.6933744221879815,x:0.4},
   {angle:0.6933744221879815,x:0.5},
   {angle:0.6933744221879815,x:0.7},
   {angle:0.6933744221879815,x:0.8},
   {angle:0.6933744221879815,x:0.8},
   {angle:0.6933744221879815,x:0.9},
   {angle:0.6933744221879815,x:1},
   {angle:0.6933744221879815,x:1.1},
   {angle:0.6933744221879815,x:1.2},
   {angle:0.6933744221879815,x:1.3},
   {angle:0.6933744221879815,x:1.4},
   {angle:0.6933744221879815,x:1.5}
]

var svg = d3.select('body').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})`)

var x = d3.scaleLinear()
    .range([0, width])
    .domain([data[0].x , data[data.length - 1].x])

var y = d3.scaleLinear()
    .range([height, 0])
    .domain([-30, 120])

var xAxis = d3.axisBottom()
    .scale(x)
    .tickValues(x.ticks(8).concat(x.domain()[0]))
    .tickFormat(d => d +'s')
    .tickPadding(8)
    .tickSizeOuter(0)

var yAxis = d3.axisLeft()
    .scale(y)
    .ticks(8)
    .tickSizeInner(-width)
    .tickSizeOuter(4)
    .tickPadding(8);

var line = d3.line()
    .x(function (d) {
        return x(d.x);
    })
    .y(function (d) {
        return y(d.angle);
    })
    .curve(d3.curveCatmullRom);

svg.append('path')
    .attr('d', line(data))
    .attr('stroke', '#ff5722')
    .attr('stroke-width', '2')
    .attr('fill', 'none');

svg.append('g')
    .call(xAxis)
    .attr('transform', `translate(0, ${height})`)

svg.append('g')
    .call(yAxis)
.tick line{
    opacity: 0.2;
}

.tick text{
    font-size: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Upvotes: 3

Views: 276

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

There is no missing tick, all those inner ticks are there! However, they are going to the right hand side of the chart, because you did this:

yAxis.tickSizeInner(-width)

In other words, your light grey gridlines are your ticks.

If you want to keep those light grey gridlines and draw the regular ticks, you have to do a different approach. Like this:

svg.append('g')
    .call(yAxis)
    .selectAll(".tick")
    .append("line")
    .attr("x2", width)
    .style("stroke", "#eee")

Here is your code with that change:

var margin = { top: 70, right: 30, bottom: 50, left: 40 }
var width = 720 - margin.left - margin.right
var height = 430 - margin.top - margin.bottom

var data = [
   {angle:0.6933744221879815,x:0.1},
   {angle:0.6933744221879815,x:0.1},
   {angle:0.6933744221879815,x:0.3},
   {angle:0.6933744221879815,x:0.4},
   {angle:0.6933744221879815,x:0.4},
   {angle:0.6933744221879815,x:0.5},
   {angle:0.6933744221879815,x:0.7},
   {angle:0.6933744221879815,x:0.8},
   {angle:0.6933744221879815,x:0.8},
   {angle:0.6933744221879815,x:0.9},
   {angle:0.6933744221879815,x:1},
   {angle:0.6933744221879815,x:1.1},
   {angle:0.6933744221879815,x:1.2},
   {angle:0.6933744221879815,x:1.3},
   {angle:0.6933744221879815,x:1.4},
   {angle:0.6933744221879815,x:1.5}
]

var svg = d3.select('body').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})`)

var x = d3.scaleLinear()
    .range([0, width])
    .domain([data[0].x , data[data.length - 1].x])

var y = d3.scaleLinear()
    .range([height, 0])
    .domain([-30, 120])

var xAxis = d3.axisBottom()
    .scale(x)
    .tickValues(x.ticks(8).concat(x.domain()[0]))
    .tickFormat(d => d +'s')
    .tickPadding(8)
    .tickSizeOuter(0)

var yAxis = d3.axisLeft()
    .scale(y)
    .ticks(8)
    .tickSizeOuter(4)
    .tickPadding(8);

var line = d3.line()
    .x(function (d) {
        return x(d.x);
    })
    .y(function (d) {
        return y(d.angle);
    })
    .curve(d3.curveCatmullRom);

svg.append('path')
    .attr('d', line(data))
    .attr('stroke', '#ff5722')
    .attr('stroke-width', '2')
    .attr('fill', 'none');

svg.append('g')
    .call(xAxis)
    .attr('transform', `translate(0, ${height})`)

svg.append('g')
    .call(yAxis)
    .selectAll(".tick")
    .append("line")
    .attr("x2", width)
    .style("stroke", "#eee")
.tick text{
    font-size: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Upvotes: 3

Related Questions