范围宽度与svg defs的轴线不匹配



我想为带有箭头的轴添加一些扩展。下面的代码基本上可以工作,但范围箭头的宽度与轴的宽度不匹配!

axis_demo()
function axis_demo() {
var width = 400
var height = 100
var margin = {left:20,top:40,right:80,bottom:20}

var svg = d3.select('body')
.append('svg')
.attr('width',width + margin.left + margin.right)
.attr('height',height + margin.top + margin.bottom)
.style('border','2px solid red')

var lc = 'grey'
var lw = 4
add_defs(svg,lw,lc)

var g = svg.append('g')
.attr('transform',`translate(${margin.left},${margin.top})`)

add_scalePoint(g,width,height)
console.log("done")
function add_scalePoint(g,width,height) {
var data = [
{day : 'Mon', value: 10},
{day : 'Tue', value: 40},
{day : 'Wed', value: 30},
{day : 'Thu', value: 60},
{day : 'Fri', value: 30}
];
var xname = 'day'
var yname = 'value'

var xdomain = data.map(d => d[xname])
var xScale = d3.scalePoint()
.domain(xdomain)
.range([0, width]);

let xaxis = g.append("g")       
.attr("class", "xaxis")
.call(d3.axisBottom(xScale) 
.tickSizeOuter(0)
.tickPadding(0))
xaxis.select('path')
.attr('stroke-width',lw)
.attr('stroke',lc)
.attr('marker-end', 'url(#arrhead)');

xaxis.selectAll('.tick line')
.attr('stroke',lc)

xaxis.selectAll("text")
.attr("transform", "rotate(-30)")
.style("text-anchor", "end");
g.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cy',-30)
.attr('cx', function(d) {
return xScale(d[xname]);
})
.attr('r', 2);
}

function add_defs(g,lw,lc) {
var xoff = 10
var dx = 4
var dy = 1.5
var arrpath = ['M',2*lw,dy+2*lw,'l',xoff,0,
0,dy,dx,-dy,-dx,-dy,0,dy]
svg
.append('defs')
.append('marker')
.attr('id', 'arrhead')
.attr('refX', 2*lw)
.attr('refY', dy+2*lw)
.attr('markerWidth',xoff + dx + 4*lw )
.attr('markerHeight', 2*dy + 4*lw)
.attr('orient', 'auto-start-reverse')
.append('path')
.attr('d', arrpath.join(' '))
.attr('stroke-miterlimit',5)
.attr('stroke', lc)
.attr('stroke-width', lw)
.attr('fill', lc);
}

function add_circle(g,cx,cy,r) {
g.append('circle')
.attr('cx',cx)
.attr('cy',cy)
.attr('r',r);
}
}
<script src="https://d3js.org/d3.v6.min.js"></script>

省略

.attr('stroke-width', lw)

构建标记时,

或将lw替换为1:

.attr('stroke-width', 1)

axis_demo()
function axis_demo() {
var width = 400
var height = 100
var margin = {left:20,top:40,right:80,bottom:20}

var svg = d3.select('body')
.append('svg')
.attr('width',width + margin.left + margin.right)
.attr('height',height + margin.top + margin.bottom)
.style('border','2px solid red')

var lc = 'grey'
var lw = 4
add_defs(svg,lw,lc)

var g = svg.append('g')
.attr('transform',`translate(${margin.left},${margin.top})`)

add_scalePoint(g,width,height)
console.log("done")
function add_scalePoint(g,width,height) {
var data = [
{day : 'Mon', value: 10},
{day : 'Tue', value: 40},
{day : 'Wed', value: 30},
{day : 'Thu', value: 60},
{day : 'Fri', value: 30}
];
var xname = 'day'
var yname = 'value'

var xdomain = data.map(d => d[xname])
var xScale = d3.scalePoint()
.domain(xdomain)
.range([0, width]);

let xaxis = g.append("g")       
.attr("class", "xaxis")
.call(d3.axisBottom(xScale) 
.tickSizeOuter(0)
.tickPadding(0))
xaxis.select('path')
.attr('stroke-width',lw)
.attr('stroke',lc)
.attr('marker-end', 'url(#arrhead)');

xaxis.selectAll('.tick line')
.attr('stroke',lc)

xaxis.selectAll("text")
.attr("transform", "rotate(-30)")
.style("text-anchor", "end");
g.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cy',-30)
.attr('cx', function(d) {
return xScale(d[xname]);
})
.attr('r', 2);
}

function add_defs(g,lw,lc) {
var xoff = 10
var dx = 4
var dy = 1.5
var arrpath = ['M',2*lw,dy+2*lw,'l',xoff,0,
0,dy,dx,-dy,-dx,-dy,0,dy]
svg
.append('defs')
.append('marker')
.attr('id', 'arrhead')
.attr('refX', 2*lw)
.attr('refY', dy+2*lw)
.attr('markerWidth',xoff + dx + 4*lw )
.attr('markerHeight', 2*dy + 4*lw)
.attr('orient', 'auto-start-reverse')
.append('path')
.attr('d', arrpath.join(' '))
.attr('stroke-miterlimit',5)
.attr('stroke', lc)
.attr('stroke-width', 1)
.attr('fill', lc);
}

function add_circle(g,cx,cy,r) {
g.append('circle')
.attr('cx',cx)
.attr('cy',cy)
.attr('r',r);
}
}
<script src="https://d3js.org/d3.v6.min.js"></script>

最新更新