add CardMap view

This commit is contained in:
axolotle
2021-04-20 15:39:41 +02:00
parent ba2f5d6767
commit 142da32978
+90 -2
View File
@@ -1,12 +1,100 @@
<template>
<component-debug :component="this" />
<b-overlay :show="loading" class="h-100">
<svg
width="100%" height="100%"
ref="svg" id="vis"
v-if="textsDepart"
: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})`"
>
<text-mini-card
:id="textsDepart[i].id"
:text-data="textsDepart[i]"
/>
</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 TextMiniCard from '@/components/text/TextMiniCard'
export default {
name: 'CardMap'
name: 'CardMap',
components: {
TextMiniCard
},
data () {
return {
loading: true,
width: 100,
height: 100,
nodes: new Array(20).fill().map((_, i) => ({ x: i, rotate: randomUniform(-25, 25)() })),
simulation: forceSimulation(),
viewBox: null
}
},
computed: {
...mapGetters(['textsDepart'])
},
methods: {
updateSize () {
const { width, height } = this.$refs.svg.getBoundingClientRect()
Object.assign(this.$data, { width, height })
}
},
created () {
this.$store.dispatch('GET_TEXTS_DEPART').then(() => {
this.loading = false
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>