123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- <template>
- <b-overlay :show="texts === undefined" class="h-100">
- <svg
- width="100%" height="100%"
- ref="svg" id="vis"
- :view-box.camel="viewBox"
- >
- <g id="cards">
- <foreignObject
- v-for="(node, i) in nodes" :key="i"
- width="500" height="300"
- :x="node.x" :y="node.y"
- :transform="`rotate(${node.rotate})`"
- >
- <node-view
- :node="texts[i]"
- mode="card"
- />
- </foreignObject>
- </g>
- </svg>
- </b-overlay>
- </template>
- <script>
- import { mapGetters } from 'vuex'
- import { select, randomUniform, zoom } from 'd3'
- import {
- forceSimulation, forceCenter, forceCollide
- } from 'd3-force'
- import { NodeView } from '@/components/nodes'
- export default {
- name: 'CardMap',
- components: {
- NodeView
- },
- data () {
- return {
- width: 100,
- height: 100,
- nodes: undefined,
- simulation: forceSimulation(),
- viewBox: null,
- texts: undefined
- }
- },
- computed: {
- ...mapGetters(['textsDepart'])
- },
- methods: {
- updateSize () {
- const { width, height } = this.$refs.svg.getBoundingClientRect()
- Object.assign(this.$data, { width, height })
- }
- },
- created () {
- this.$store.dispatch('INIT_LIBRARY_MAP').then(data => {
- this.texts = data
- this.nodes = data.map((node, i) => {
- return { x: i, rotate: randomUniform(-25, 25)() }
- })
- this.$nextTick(() => {
- this.updateSize()
- this.viewBox = `0 0 ${this.width} ${this.height}`
- const svg = select('#vis')
- const g = select('#cards')
- svg.call(zoom()
- .extent([[0, 0], [this.width, this.height]])
- .scaleExtent([-5, 8])
- .on('zoom', zoomed))
- function zoomed ({ transform }) {
- g.attr('transform', transform)
- }
- this.simulation
- .nodes(this.nodes)
- .force('collide', forceCollide(d => randomUniform(250, 350)()))
- .force('center', forceCenter(this.width * 0.5, this.height * 0.5))
- .alphaDecay([0.02])
- })
- })
- }
- }
- </script>
- <style lang="scss" scoped>
- foreignObject {
- transform-origin: 250, 150;
- }
- </style>
|