【问题标题】:Zoom left and right axis for dual scaled chart in d3d3中双比例图表的左右轴缩放
【发布时间】:2014-04-27 23:03:48
【问题描述】:

我有使用 d3 的双比例折线图,下面是 coffescript

# bottom axis
xScale = d3.time.scale().range([0,width]).domain(d3.extent(data, (d) -> d.date))
xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(5)
# left axis
yLeftMax = d3.max(data, (d) -> d.price)
yLeftScale = d3.scale.linear().domain([0, yLeftMax]).range([height, 0])
yLeftAxis = d3.svg.axis().scale(yLeftScale).orient("left")
# right axis
yRightMax = d3.max(data, (d) -> d.yoy)
yRightMin = d3.min(data, (d) -> d.yoy)
yRightAbsMax = Math.max(Math.abs(yRightMin), Math.abs(yRightMax))
yRightScale = d3.scale.linear().domain([-yRightAbsMax, yRightAbsMax]).range([height, 0])
yRightAxis = d3.svg.axis().scale(yRightScale).orient("right")
myZoom = ->
  canvas.select("._x._axis").call xAxis
  #canvas.select(".axisLeft").call yLeftAxis  // can't zoom left axis here
  canvas.select(".axisRight").call yRightAxis // Zoom right axis
  canvas.select(".line1").attr("d", line1(data)) // Zoom left scaled line
  canvas.select(".line2").attr("d", line2(data)) // Zoom right scaled line
zoom = d3.behavior.zoom()
 .x(xScale) // set xScale for zoom 
 #.y(yLeftScale) // can't set left yScale for zoom here
 .y(yRightScale) // set right yScale for zoom  
 .scaleExtent([1,20]) # 20x times zoom
 .on("zoom", myZoom)
...

问题是,当我使用缩放时,左或右 y 轴都被缩放,即我无法在两个 y 尺度上都进行缩放。

【问题讨论】:

  • 您必须在缩放事件处理程序中设置其他 y 比例的范围。
  • @LarsKotthoff 我认为您的意思是 。规模的范围应该保持[0, height],不是吗? :)
  • 啊,是的,你是对的,我的错 :)

标签: javascript svg d3.js zooming


【解决方案1】:

在您的myZoom 函数中,您可以显式设置yLeftScaledomain

myZoom = ->
  scale = d3.event.scale
  translate = d3.event.translate

  # Haven't verified these calculations. Is it scale first or translate first?
  # See `alternate answer` below for a better approach
  yLeftScale.domain([0 + translate[1], yLeftMax / scale + translate[1])
  canvas.select("._x._axis").call xAxis
  canvas.select(".axisLeft").call yLeftAxis  # can't zoom left axis here
  canvas.select(".axisRight").call yRightAxis # Zoom right axis
  canvas.select(".line1").attr("d", line1(data)) # Zoom left scaled line
  canvas.select(".line2").attr("d", line2(data)) # Zoom right scaled line

替代解决方案是拥有两个独立的缩放行为并控制另一个 zoom 行为,而不是手动更新 domains。我发现这更健壮,虽然有点冗长。

zoomLeft = d3.behavior.zoom()
 .x(xScale) # set xScale for zoom 
 .y(yLeftScale) # can't set left yScale for zoom here
 .scaleExtent([1,20]) # 20x times zoom

myZoom 中,设置zoomLeftscaletranslate

myZoom = ->
  zoomLeft.scale(zoom.scale()).translate(zoom.translate())

  canvas.select("._x._axis").call xAxis
  canvas.select(".axisLeft").call yLeftAxis  # can't zoom left axis here
  canvas.select(".axisRight").call yRightAxis # Zoom right axis
  canvas.select(".line1").attr("d", line1(data)) # Zoom left scaled line
  canvas.select(".line2").attr("d", line2(data)) # Zoom right scaled line

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    相关资源
    最近更新 更多