step.vue 4.1 KB

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