我试图用两组不同的轴绘制散点图。第一组轴应固定在图的左侧和底部,可缩放和可缩放(即传统的绘图轴)。第二组轴应固定在图上,并穿过图的中心。
当图形放大时,两组轴不会以相同的速率缩放,这意味着外轴不能准确反映绘制数据的x / y。
我有一个jsfiddle展示了目前正在发生的事情http://jsfiddle.net/0kctabch/
编辑:根据@mgold的建议,从内轴为子轴的图层中删除了比例变换。现在,内部轴在缩放时根本没有缩放。新小提琴:http://jsfiddle.net/0kctabch/1/
代码如下:
var width = 500,
height = 500,
margin = {
top: 0,
right: 0,
bottom: 25,
left: 70
};
var pointWidth = 2,
defaultZoom = 1,
maxWidth = 32768;
var palette = {
"lightgray": "#819090",
"gray": "#708284",
"mediumgray": "#536870",
"darkgray": "#475B62",
"darkblue": "#0A2933",
"darkerblue": "#042029",
"paleryellow": "#FCF4DC",
"paleyellow": "#EAE3CB",
"yellow": "#A57706",
"orange": "#BD3613",
"red": "#D11C24",
"harshRed": "#ff0000",
"pink": "#C61C6F",
"harshPink": "#ff6699",
"purple": "#595AB7",
"blue": "#2176C7",
"green": "#259286",
"yellowgreen": "#738A05"
}, colors = {
selectedPoint: palette.darkerblue,
background: palette.mediumgray,
};
//Create scales
var xScale = d3.scale.linear()
.domain([0, maxWidth])
.range([-1 * (maxWidth * (pointWidth / 2)), (maxWidth * (pointWidth / 2))]);
var yScale = d3.scale.linear()
.domain([0, maxWidth])
.range([-1 * (maxWidth * (pointWidth / 2)), (maxWidth * (pointWidth / 2))]);
var bottomScale = d3.scale.linear()
.domain([0, maxWidth])
.range([-1 * (maxWidth * (pointWidth / 2)), (maxWidth * (pointWidth / 2))]);
var leftScale = d3.scale.linear()
.domain([0, maxWidth])
.range([-1 * (maxWidth * (pointWidth / 2)), (maxWidth * (pointWidth / 2))]);
// Create Axes
var xAxis = d3.svg.axis()
.scale(xScale)
.ticks(640)
var yAxis = d3.svg.axis()
.scale(yScale)
.ticks(640)
.orient('left')
var bottomAxis = d3.svg.axis()
.scale(bottomScale)
.ticks(640)
.tickSize(-height)
var leftAxis = d3.svg.axis()
.scale(leftScale)
.ticks(640)
.tickSize(-width)
.orient('left')
// Create map
var map = d3.select('#map').append('svg')
.style('background', colors.background)
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom);
function createMap() {
allPoints = map.append('g')
.attr('id','allPoints');
xGuide = allPoints.append('g')
xAxis(xGuide)
xGuide.attr('transform', 'translate(' + (width/2 + margin.left) + ', ' + (height/2) + ')')
.selectAll('path')
.style({ fill: 'none', stroke: '#000' })
xGuide.selectAll('line')
.style({ stroke: '#000' })
yGuide = allPoints.append('g')
yAxis(yGuide);
yGuide.attr('transform', 'translate(' + (width/2 + margin.left) + ', ' + (height/2) + ')')
.selectAll('path')
.style({ fill: 'none', stroke: '#000' })
yGuide.selectAll('line')
.style({ stroke: '#000' })
bottomGuide = map.append('g')
bottomAxis(bottomGuide)
bottomGuide.attr('class', 'x axis')
bottomGuide.attr('transform', 'translate(' + (width/2 + margin.left) + ', ' + height + ')')
.selectAll('path')
.style({ fill: 'none', stroke: '#000' })
bottomGuide.selectAll('line')
.style({ stroke: '#000' })
leftGuide = map.append('g')
leftAxis(leftGuide);
leftGuide.classed('y axis', true)
leftGuide.attr('transform', 'translate(' + margin.left + ', ' + (height/2) + ')')
.selectAll('path')
.style({ fill: 'none', stroke: '#000' })
leftGuide.selectAll('line')
.style({ stroke: '#000' })
applyZoom();
}
function applyZoom() {
var setZoom = d3.behavior.zoom()
.scale(1)
.scaleExtent([0, 10])
.x(bottomScale)
.y(leftScale)
.on('zoom', zoom);
d3.select('#map svg').call(setZoom);
}
function zoom() {
d3.select('#allPoints')
// .attr('transform', 'translate(' + d3.event.translate.join(',') + ')scale(' + d3.event.scale + ')');
.attr('transform', 'translate(' + d3.event.translate.join(',') + ')');
map.select('.x.axis').call(bottomAxis);
map.select('.y.axis').call(leftAxis);
}
createMap();