programing

직접 DOM조작하지 않고 d3-axis을 그리세요.

prostudy 2022. 8. 22. 21:37
반응형

직접 DOM조작하지 않고 d3-axis을 그리세요.

DOM을 직접 조작하지 않고 d3-axis를 사용하는 방법이 있습니까?D3.js는 Vue.js의 도우미 기능에 사용할 때 Vue.js를 보완합니다(특히).d3-scale).

현재 단순한 Vue 템플릿을 사용하여 SVG를 생성하고 있습니다.축을 생성하기 위해, 나는 먼저 create를 만들고 있다.<g ref="axisX">소자를 호출합니다.d3.select(this.$refs.axisX).call(d3.axisBottom(this.scale.x)).

나는 그것을 사용하는 것을 피하고 싶다.d3.selectDOM 의 직접 변경을 방지합니다.동작은 좋지만 Vue.js의 스코프 스타일과 모순됩니다.

에 접속할 수 있는 방법이 있습니까?d3-axisDOM 요소에서 호출하지 않고요?이 기능에 액세스 할 수 있으면 편리합니다.path생성은 DOM을 경유하지 않고 독립적으로 기능합니다.

여기 샘플 CodePen:https://codepen.io/thibautg/pen/BYRBXW.

사용자 지정 지시문을 요구한다 이것은 상황이다.사용자 지정 지침을 당신은 그들에 부착되는 요소 안에는 DOM을 조작할 수 있도록 한다.

이 경우 어떤 축과 어떤 값이 계산되는지 인수를 사용하는 지시문을 작성했습니다.축이 x인지 y인지에 따라 호출합니다.axisBottom또는axisLeft와 함께scale[axis].

더 이상 보지 마.디렉티브는 업데이트될 때마다 호출됩니다.당신이 수표를 넣어 볼 수도 있어요scale특히 이전 값과 달라졌습니다.

new Vue({
  el: "#app",
  data() {
    return {
      width: 600,
      height: 400,
      margin: {
        top: 20,
        right: 20,
        bottom: 20,
        left: 20
      },
      items: [
        { name: "a", val: 10 },
        { name: "b", val: 8 },
        { name: "c", val: 1 },
        { name: "d", val: 5 },
        { name: "e", val: 6 },
        { name: "f", val: 3 }
      ]
    };
  },
  computed: {
    outsideWidth() {
      return this.width + this.margin.left + this.margin.right;
    },
    outsideHeight() {
      return this.height + this.margin.top + this.margin.bottom;
    },
    scale() {
      const x = d3
        .scaleBand()
        .domain(this.items.map(x => x.name))
        .rangeRound([0, this.width])
        .padding(0.15);
      const y = d3
        .scaleLinear()
        .domain([0, Math.max(...this.items.map(x => x.val))])
        .rangeRound([this.height, 0]);
      return { x, y };
    }
  },
  directives: {
    axis(el, binding) {
      const axis = binding.arg;
      const axisMethod = { x: "axisBottom", y: "axisLeft" }[axis];
      const methodArg = binding.value[axis];

      d3.select(el).call(d3[axisMethod](methodArg));
    }
  }
});
rect.bar {
  fill: steelblue;
}
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
<div id="app">
  <svg :width="outsideWidth"
       :height="outsideHeight">
    <g :transform="`translate(${margin.left},${margin.top})`">
      <g class="bars">
        <template v-for="item in items">
          <rect class="bar"
                :x="scale.x(item.name)"
                :y="scale.y(item.val)"
                :width="scale.x.bandwidth()"
                :height="height - scale.y(item.val)"
                />
        </template>
        <g v-axis:x="scale" :transform="`translate(0,${height})`"></g>
        <g v-axis:y="scale"></g>
      </g>
    </g>
  </svg>
</div>

언급URL : https://stackoverflow.com/questions/48726636/draw-d3-axis-without-direct-dom-manipulation

반응형