【近況】レオパに手を出した
過去記事にて、カナヘビ(ドラ・チャンさん)のために購入したコオロギが爆増したので消費者を増やそうということを抜かしてましたが、とうとうレオパードゲッコー(ヒョウモントカゲモドキ)をお迎えしました。
品種(モルフ)はスノーブラックナイト(スノー系とブラックナイトの子)で、
まだまだバブみ溢れる可愛らしい女の子です。
トカゲ【もどき】どころか、ワニもどきやドラゴンもどきと呼ばれるぐらいに、
スクスクとブクブクと育てて行こうかと(親バカ
拡張性を持たせるために簡単に作った(要約:今回はやる気がないのでちょっと手抜き
ワークフローとかのフロー図だったり、組織図みたいなExcelのオブジェクトみたいなのを、
Webで動的に作りたい的な時の雛形として参考にしてもらえれてばということでこんなソースを作ってみた。
ソース
<script setup lang="ts">
import { computed, reactive } from 'vue';
const routeList = reactive([
{ id: 1, x: 50, y: 80, user: "起票者", next: [2, 3] },
{ id: 2, x: 150, y: 60, user: "承認者A", next: [4] },
{ id: 3, x: 200, y: 150, user: "承認者C", next: [5] },
{ id: 4, x: 230, y: 60, user: "承認者B", next: [5] },
{ id: 5, x: 350, y: 60, user: "最終承認者", next: [] },
]
);
const routeLine = computed(() => {
const lineList = []
for (let i = 0; i < routeList.length; i++) {
const route = routeList[i]
for (let j = 0; j < route.next.length; j++) {
const next = routeList.find(r => r.id === route.next[j])
lineList.push({ x1: route.x, y1: route.y, x2: next.x, y2: next.y })
}
}
return lineList
})
</script>
<template>
<svg width="500" height="500">
<line v-for="l of routeLine" :x1="l.x1" :y1="l.y1" :x2="l.x2" :y2="l.y2" style="stroke:rgb(0,0,0);stroke-width:2" />
<template v-for="r of routeList">
<image href="/ai_character01_smile.png" width="60" height="60" :x="r.x - 30" :y="r.y -30" />
<text :x="r.x - 30" :y="r.y + 45" fill="black">{{ r.user }}</text>
</template>
</svg>
</template>
<style scoped></style>
※image
タグで表示しているアイコンはいらすとやからダウンロードしてpublicフォルダにぶち込んだものとなります。
出力されるものがこちら
今はコンポーネントに固定値で値を設定していますが、definePropsとかで値を渡したりすれば、
色んなデータパターンでルートを生成することが出来るね。
社員のアバター画像をrouteList
にimgPath: string;
でもたせてもいいね。
後は現在どこで滞ってるかどうかもisActive: boolean
とか付けて、CSSで点滅させるとか色々と拡張は出来るね。
※やる気がないのでそこまで作り込まなかったけど。。。
あまりためにならない、ちょっとだけ解説
ルート情報については、1つ1つのオブジェクト(ここで言う起票者や承認者)を配列で持って、
そのオブジェクトの次にどのオブジェクトが紐づくかはnext: number[]
(idの配列)で持たせることにより、
1つのオブジェクトから複数の線を引くことに対応しました。
※例では起票者(id:1)はnext: [2, 3]
となっており、承認者A/Cへのルートが出来てる感じです
SVGは何も指定しないとタグ順にどんどん上へオブジェクトが積み重ねられるため、
先にline
タグで画像間の線をひいてから、画像を配置してテキストを配置した感じにしてます。