step.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template>
  2. <rect
  3. @click="emit('click')"
  4. v-bind="rectBound"
  5. :rx="style.rectRadius"
  6. :ry="style.rectRadius"
  7. :fill="style.rectBgColor"
  8. :stroke="style.rectBorderColor"
  9. :stroke-width="style.rectBorderWidth"
  10. style="cursor: pointer"
  11. >
  12. </rect>
  13. <template v-if="step.raw.hosts">
  14. <rect
  15. v-for="(_, index) in step.raw.hosts"
  16. :x="hostBounds[index].x"
  17. :y="hostBounds[index].y"
  18. :width="hostBounds[index].width"
  19. :height="hostBounds[index].height"
  20. :rx="style.rectRadius"
  21. :ry="style.rectRadius"
  22. :fill="
  23. _.status === 'success'
  24. ? '#30d567'
  25. : _.status === 'error'
  26. ? '#ff4238'
  27. : _.status === 'running'
  28. ? '#ecf752'
  29. : _.status === 'waiting'
  30. ? '#89beb2'
  31. : 'd4f8c3'
  32. "
  33. :stroke="'#333'"
  34. :stroke-width="style.rectBorderWidth"
  35. @click="emit('clickHost', step.raw.hosts[index])"
  36. style="cursor: pointer"
  37. >
  38. </rect>
  39. <text
  40. v-for="(hostTex, i) in hostTextAttribs"
  41. @click="emit('clickHost', step.raw.hosts[i])"
  42. :font-family="fontFamily"
  43. :fill="'#333'"
  44. dominant-baseline="middle"
  45. :font-size="hostFontSize"
  46. text-anchor="middle"
  47. v-bind="hostTex"
  48. style="cursor: pointer"
  49. >
  50. {{ step.raw.hosts[i].host }}
  51. </text>
  52. </template>
  53. <text
  54. @click="emit('click')"
  55. :font-family="fontFamily"
  56. :fill="style.textColor"
  57. :font-size="fontSize"
  58. dominant-baseline="middle"
  59. text-anchor="middle"
  60. v-bind="textAttrib"
  61. style="cursor: pointer"
  62. >
  63. {{ step.displayName }}
  64. </text>
  65. <template v-if="lines.length">
  66. <polyline
  67. v-for="line in lines"
  68. :points="line.join(',')"
  69. fill="none"
  70. :stroke="style.lineColor"
  71. :stroke-width="style.lineWidth"
  72. />
  73. </template>
  74. </template>
  75. <script setup lang="ts">
  76. import { computed } from 'vue'
  77. import { NStep } from './helper'
  78. const props = defineProps<{
  79. step: NStep
  80. margin: number[]
  81. padding: number[]
  82. fontSize: number
  83. fontFamily: string
  84. lines: number[][]
  85. hostMargin: number[]
  86. hostPadding: number[]
  87. hostFontSize: number
  88. style: {
  89. lineColor: string
  90. lineWidth: number
  91. textColor: string
  92. rectBorderColor: string
  93. rectBorderWidth: number
  94. rectBgColor: string
  95. rectRadius: number
  96. }
  97. }>()
  98. const emit = defineEmits<{ (e: 'click'): void; (e: 'clickHost', host: any): void }>()
  99. const rectBound = computed(() => ({
  100. x: props.step.bound.left + props.margin[1],
  101. y: props.step.bound.top + props.margin[0],
  102. width: props.step.bound.width - props.margin[1] * 2,
  103. height: props.step.bound.height - props.margin[0] * 2,
  104. }))
  105. const textAttrib = computed(() => ({
  106. x: rectBound.value.x + rectBound.value.width / 2,
  107. y: rectBound.value.y + props.padding[0] + props.fontSize / 2,
  108. }))
  109. const hostBounds = computed(() => {
  110. let left =
  111. rectBound.value.x +
  112. props.padding[1] +
  113. (rectBound.value.width - props.padding[1] * 2 - props.step.raw.hostSize.width) / 2
  114. let top = rectBound.value.y + rectBound.value.height - props.step.raw.hostSize.height
  115. const hosts = props.step.raw.hosts
  116. return hosts.map((host: any) => {
  117. const x = left + host.bound.left + props.hostMargin[1]
  118. const y = top + props.hostMargin[0] + host.bound.top
  119. return {
  120. x,
  121. y,
  122. width: host.bound.width - props.hostMargin[1] * 2,
  123. height: host.bound.height - props.hostMargin[0] * 2,
  124. }
  125. })
  126. })
  127. const hostTextAttribs = computed(() =>
  128. hostBounds.value.map((hostBound: any) => ({
  129. x: hostBound.x + hostBound.width / 2,
  130. y: hostBound.y + props.hostPadding[0] + props.hostFontSize / 2,
  131. }))
  132. )
  133. </script>