(2019) 2 つのティック間の距離のみを計算する代わりに、非線形スケールをカバーするようにtechjackerソリューションを拡張できます。ティック間のすべての距離を含む配列を持つことができます。
// ticksDistance is constant for a specific x_scale
const getTicksDistance = (scale) => {
const ticks = scale.ticks();
const spaces = []
for(let i=0; i < ticks.length - 1; i++){
spaces.push(scale(ticks[i+1]) - scale(ticks[i]))
}
return spaces;
};
//you have to recalculate when x_scale or ticks change
const ticksSpacingPow = getTicksDistance(x_scale_pow);
ticksSpacingPow
すべての距離の配列です
以下の例では、目盛り間の距離の半分に楕円を描画します。
// normal
svg.append("g")
.attr("class", "x-axis")
.attr("transform", "translate(0,20)")
.call(x_axis_pow)
.selectAll('.tick')
.append('ellipse')
.attr('fill', 'red')
.attr('rx', '2px')
.attr('ry', '10px')
.attr('cx', (d,i)=> ticksSpacingPow[i]/2)
ps。最新の D3v5 の使用
const x_scale_pow = d3.scalePow().exponent(2)
.domain([0,20000])
.range([0, 960]);
const x_axis_pow = d3.axisBottom()
.scale(x_scale_pow)
.ticks(10)
// ticksDistance is constant for a specific x_scale
const getTicksDistance = (scale) => {
const ticks = scale.ticks();
const spaces = []
for(let i=0; i < ticks.length - 1; i++){
spaces.push(scale(ticks[i+1]) - scale(ticks[i]))
}
return spaces;
};
//you have to recalculate when x_scale or ticks change
const ticksSpacingPow = getTicksDistance(x_scale_pow);
const svg = d3.select("body").append("svg")
.attr("width", "500px")
.attr("height","350px")
.style("width", "100%")
.style("height", "auto");
// normal
svg.append("g")
.attr("class", "x-axis")
.attr("transform", "translate(0,20)")
.call(x_axis_pow)
.selectAll('.tick')
.append('ellipse')
.attr('fill', 'red')
.attr('rx', '2px')
.attr('ry', '10px')
.attr('cx', (d,i)=> ticksSpacingPow[i]/2)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>