You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
5.8 KiB

2 years ago
  1. <template>
  2. <v-main>
  3. <v-container fluid>
  4. <v-row justify="center">
  5. <v-col cols="12" md="9">
  6. <v-card>
  7. <v-card-title>
  8. <v-chip-group v-model="selectedLabelIndex" column>
  9. <v-chip
  10. v-for="item in labels"
  11. :key="item.id"
  12. :color="item.backgroundColor"
  13. filter
  14. :text-color="$contrastColor(item.backgroundColor)"
  15. >
  16. {{ item.text }}
  17. <v-avatar
  18. v-if="item.suffixKey"
  19. right
  20. color="white"
  21. class="black--text font-weight-bold"
  22. >
  23. {{ item.suffixKey }}
  24. </v-avatar>
  25. </v-chip>
  26. </v-chip-group>
  27. </v-card-title>
  28. <v-divider />
  29. <v-bounding-box
  30. :rectangles="filteredRectangles"
  31. :highlight-id="highlightId"
  32. :image-url="imageUrl"
  33. :labels="bboxLabels"
  34. :selected-label="selectedLabel"
  35. :scale="scale"
  36. @add-rectangle="addRectangle"
  37. @update-rectangle="updateRectangle"
  38. @delete-rectangle="deleteRectangle"
  39. @update-scale="updateScale"
  40. @select-rectangle="selectRectangle"
  41. />
  42. </v-card>
  43. </v-col>
  44. <v-col cols="12" md="3">
  45. <list-metadata :metadata="meta" />
  46. <region-list
  47. class="mt-4"
  48. :regions="regionList"
  49. @change-visibility="changeVisibility"
  50. @delete-region="deleteRectangle"
  51. @hover-region="hoverRegion"
  52. @unhover-region="unhoverRegion"
  53. />
  54. </v-col>
  55. </v-row>
  56. </v-container>
  57. </v-main>
  58. </template>
  59. <script>
  60. import VBoundingBox from '@/components/tasks/boundingBox/VBoundingBox.vue'
  61. import ListMetadata from '@/components/tasks/metadata/ListMetadata'
  62. import RegionList from '@/components/tasks/image/RegionList.vue'
  63. export default {
  64. components: {
  65. ListMetadata,
  66. VBoundingBox,
  67. RegionList
  68. },
  69. layout: 'demo',
  70. data() {
  71. return {
  72. imageUrl: require('~/assets/images/demo/cat.jpeg'),
  73. rectangles: [
  74. {
  75. id: 'uuid',
  76. label: 1,
  77. x: 10,
  78. y: 10,
  79. width: 100,
  80. height: 100
  81. }
  82. ],
  83. labels: [
  84. {
  85. id: 1,
  86. text: 'Cat',
  87. prefixKey: null,
  88. suffixKey: 'c',
  89. backgroundColor: '#7c20e0',
  90. textColor: '#ffffff'
  91. },
  92. {
  93. id: 2,
  94. text: 'Dog',
  95. prefixKey: null,
  96. suffixKey: 'd',
  97. backgroundColor: '#fbb028',
  98. textColor: '#000000'
  99. }
  100. ],
  101. meta: { wikiPageId: 2 },
  102. selectedLabelIndex: undefined,
  103. selectedRectangle: undefined,
  104. scale: 1,
  105. visibilities: {},
  106. highlightId: null
  107. }
  108. },
  109. computed: {
  110. bboxLabels() {
  111. return this.labels.map((label) => {
  112. return {
  113. id: label.id,
  114. name: label.text,
  115. color: label.backgroundColor
  116. }
  117. })
  118. },
  119. selectedLabel() {
  120. if (this.selectedLabelIndex !== undefined) {
  121. return this.labels[this.selectedLabelIndex]
  122. } else {
  123. return undefined
  124. }
  125. },
  126. regionList() {
  127. return this.rectangles.map((rectangle) => {
  128. return {
  129. id: rectangle.id,
  130. category: this.labels.find((label) => rectangle.label === label.id).text,
  131. color: this.labels.find((label) => rectangle.label === label.id).backgroundColor,
  132. visibility: rectangle.id in this.visibilities ? this.visibilities[rectangle.id] : true
  133. }
  134. })
  135. },
  136. filteredRectangles() {
  137. return this.rectangles.filter((rectangle) => this.visibilities[rectangle.id] !== false)
  138. }
  139. },
  140. watch: {
  141. selectedLabel(newLabel) {
  142. if (newLabel !== undefined && !!this.selectedRectangle) {
  143. const rect = this.rectangles.find((r) => r.id === this.selectedRectangle.id)
  144. rect.label = newLabel.id
  145. this.updateRectangle(rect)
  146. }
  147. }
  148. },
  149. methods: {
  150. addRectangle(rectangle) {
  151. console.log('addRectangle', rectangle)
  152. this.rectangles.push(rectangle)
  153. this.visibilities[rectangle.id] = true
  154. this.selectedLabelIndex = undefined
  155. },
  156. updateRectangle(rectangle) {
  157. console.log('updateRectangle', rectangle)
  158. const index = this.rectangles.findIndex((r) => r.id === rectangle.id)
  159. if (index !== -1) {
  160. this.$set(this.rectangles, index, rectangle)
  161. }
  162. },
  163. deleteRectangle(rectangleId) {
  164. console.log('deleteRectangle', rectangleId)
  165. this.rectangles = this.rectangles.filter((r) => r.id !== rectangleId)
  166. delete this.visibilities[rectangleId]
  167. },
  168. changeVisibility(regionId, visibility) {
  169. console.log('changeVisibility', regionId, visibility)
  170. this.$set(this.visibilities, regionId, visibility)
  171. this.visibilities = Object.assign({}, this.visibilities)
  172. },
  173. hoverRegion(regionId) {
  174. console.log('hoverRegion', regionId)
  175. this.highlightId = regionId
  176. },
  177. unhoverRegion(regionId) {
  178. console.log('unhoverRegion', regionId)
  179. this.highlightId = null
  180. },
  181. selectRectangle(rectangleId) {
  182. console.log('selectRectangle', rectangleId)
  183. if (rectangleId) {
  184. this.selectedRectangle = this.rectangles.find((r) => r.id === rectangleId)
  185. this.selectedLabelIndex = this.labels.findIndex(
  186. (l) => l.id === this.selectedRectangle.label
  187. )
  188. } else {
  189. this.selectedRectangle = undefined
  190. this.selectedLabelIndex = undefined
  191. }
  192. },
  193. zoomOut() {
  194. this.scale -= 0.1
  195. },
  196. zoomIn() {
  197. this.scale += 0.1
  198. },
  199. updateScale(scale) {
  200. this.scale = scale
  201. }
  202. }
  203. }
  204. </script>