【问题标题】:How to set up d3-zoom correctly in vue?如何在 vue 中正确设置 d3-zoom?
【发布时间】:2021-06-28 05:43:23
【问题描述】:

我有 svg 用于渲染场地座位。所有席位都按部门分组。我需要在座位点击事件上,放大该扇区中的那些座位,当我点击另一个扇区时,它应该缩小并再次放大新扇区。这是我想要的示例:https://observablehq.com/@d3/zoom-to-bounding-box?collection=@d3/d3-zoom

目前我使用 svgPanZoom.js 库来操作 svg(我知道它使用矩阵而不是 viewBox)。 D3 似乎有点难,你能告诉我一个 d3 的替代方案吗?

这是我的代码:

<svg width="100%"
     xmlns="http://www.w3.org/2000/svg"
     ref="venueMap" id="venue-map"
     opacity="1"
     class="seat-map"
     @mousedown.prevent="startDrag"
     @touchstart="startDrag"
     @mousemove="updateEndDragPoint"
     @mouseup="stopDrag"
     @touchend="stopDrag"
     @touchcancel="stopDrag">

  <image :href="layoutImage.url"
         :width="layoutImage.width - (+layoutImage.width * 0.01 * 60)"
         :height="layoutImage.height - (+layoutImage.height * 0.01 * 60)">
  </image>

  <rect
    class="selectArea"
    v-show="shouldDisplaySelectRect"
    :x="dragData.start.x < dragData.end.x ? dragData.start.x : dragData.end.x"
    :y="dragData.start.y < dragData.end.y ? dragData.start.y : dragData.end.y"
    :width="Math.abs(dragData.start.x - dragData.end.x)"
    :height="Math.abs(dragData.start.y - dragData.end.y)">
  </rect>

  <g v-for="(sector,sectorIndex) in placements">
    <g v-for="(row, rowIndex) in sector">
      <rect v-for="(seat, seatIndex) in row"
            :key="seatIndex + 'A'"
            :x="seat.x"
            :y="seat.y"
            :class="seatStyle(seat)"
            class="seat-rect"
            height="9"
            width="9"
            @mouseover="mouseOverSeat(seat, $event)"
            @mouseout="mouseOutFromSeat($event)"
            @click="selectSeat(seat, {sectorIndex, rowIndex}, $event)">
      </rect>
    </g>
  </g>


  <PolygonComponent v-for="(sector, index) in sectors"
                    :key="index"
                    :sector-index="index"
                    :sector="sector"
                    :sector-text-positions="sectorTextPosition">
  </PolygonComponent>

</svg>

【问题讨论】:

    标签: vue.js svg d3.js zoom-sdk svgpanzoom


    【解决方案1】:

    这是一个简单的缩放示例(Vue + D3 V6

    我建议显式传递 SVG 宽度和高度,而不是使用 viewBox:

      const onZoom = (container, event) => container.attr('transform', event.transform);
        
    const initView = (ref, width, height) => {    
          // Init SVG container
          const svg = d3.select(ref);
          const container = svg.append('g')
            .classed('container', true);
                
          // Draw something under your container  
          container.append('circle')
            .attr('r', 50)
            .style('fill', '#aaa')
            .style('cursor', 'pointer');
              
          // Init D3 zoom
          const zoom = d3.zoom()
            .scaleExtent([0.5, 10])
            .on('zoom', e => onZoom(container, e));
          svg.call(zoom);
                
          // Center container within SVG    
          const centered = d3.zoomIdentity
            .translate(width/2, height/2);
          svg.call(zoom.transform, centered);  
        }
        
        Vue.component('d3-component', {
          props: ['width', 'height'],
          mounted() {
            initView(this.$refs.svg, this.width, this.height);
          },
          template: '<svg ref="svg" :width="width" :height="height"></svg>'
        })
        
        new Vue({ el: '#d3-zoom-demo' })
        svg {
          background-color: #ccc;
        }
      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.6.2/d3.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    
    <div id="d3-zoom-demo">
      <d3-component width="200" height="150"/>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-05
      • 1970-01-01
      • 2018-06-23
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多