fluency-v8-components 1.3.4 → 1.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/dist/fluency-v8-components.es.js +1 -1
  2. package/dist/fluency-v8-components.umd.js +31 -31
  3. package/dist/{index-Dxs_Gn5T.mjs → index-BBxccHNP.mjs} +53 -47
  4. package/dist/index.css +1 -1
  5. package/dist/{index.es-YeMpD96e.mjs → index.es-D_XhLSeH.mjs} +1 -1
  6. package/package.json +3 -2
  7. package/src/assets/images/ai.svg +1 -0
  8. package/src/assets/images/github-dark.svg +1 -0
  9. package/src/assets/images/github.svg +1 -0
  10. package/src/assets/images/high-priority.svg +1 -0
  11. package/src/assets/images/power-off.svg +1 -0
  12. package/src/assets/images/save.svg +1 -0
  13. package/src/assets/index.ts +15 -0
  14. package/src/assets/main.css +505 -0
  15. package/src/assets/prism-theme.css +290 -0
  16. package/src/components/buttons/ActionButtons.vue +374 -0
  17. package/src/components/buttons/DropdownButton.vue +104 -0
  18. package/src/components/buttons/IconButton.vue +63 -0
  19. package/src/components/buttons/ImageButton.vue +16 -0
  20. package/src/components/buttons/MenuButton.vue +138 -0
  21. package/src/components/buttons/SubmitButtons.vue +51 -0
  22. package/src/components/buttons/TextButton.vue +40 -0
  23. package/src/components/charts/AlertChart.vue +376 -0
  24. package/src/components/charts/BarChart.vue +212 -0
  25. package/src/components/charts/BarChartHorizontal.vue +243 -0
  26. package/src/components/charts/CronChart.vue +146 -0
  27. package/src/components/charts/EmptyChart.vue +76 -0
  28. package/src/components/charts/GradientChart.vue +310 -0
  29. package/src/components/charts/LineChart.test.js +59 -0
  30. package/src/components/charts/LineChart.vue +434 -0
  31. package/src/components/charts/PieChart.vue +293 -0
  32. package/src/components/charts/ProgressChart.vue +106 -0
  33. package/src/components/charts/StackedChart.vue +364 -0
  34. package/src/components/charts/StackedChartClustered.vue +395 -0
  35. package/src/components/charts/TimelineChart.vue +215 -0
  36. package/src/components/charts/WorkflowChart.vue +520 -0
  37. package/src/components/common/AutoCompleteSearchBar.vue +100 -0
  38. package/src/components/common/AutoRefreshButton.vue +53 -0
  39. package/src/components/common/Breadcrumb.vue +45 -0
  40. package/src/components/common/ButtonToggle.vue +24 -0
  41. package/src/components/common/Card.vue +116 -0
  42. package/src/components/common/Carousel.vue +66 -0
  43. package/src/components/common/CategoryCard.vue +28 -0
  44. package/src/components/common/CodeEditor.vue +59 -0
  45. package/src/components/common/DatePicker.vue +21 -0
  46. package/src/components/common/DatePickerInput.vue +109 -0
  47. package/src/components/common/Dialog.vue +103 -0
  48. package/src/components/common/EditorHeading.vue +10 -0
  49. package/src/components/common/EventList.vue +41 -0
  50. package/src/components/common/Facet.vue +206 -0
  51. package/src/components/common/Feed.vue +58 -0
  52. package/src/components/common/Flag.vue +27 -0
  53. package/src/components/common/HomeCard.vue +20 -0
  54. package/src/components/common/ItemBox.vue +49 -0
  55. package/src/components/common/Loading.vue +19 -0
  56. package/src/components/common/LoadingDots.vue +12 -0
  57. package/src/components/common/PageHeading.vue +30 -0
  58. package/src/components/common/Pagination.vue +105 -0
  59. package/src/components/common/Popover.vue +24 -0
  60. package/src/components/common/PowerToggle.vue +130 -0
  61. package/src/components/common/ProgressBar.vue +33 -0
  62. package/src/components/common/RadioButtons.vue +52 -0
  63. package/src/components/common/Schedule.vue +79 -0
  64. package/src/components/common/SearchBar.vue +30 -0
  65. package/src/components/common/Separator.vue +3 -0
  66. package/src/components/common/Slideout.vue +95 -0
  67. package/src/components/common/Sort.vue +83 -0
  68. package/src/components/common/Table.vue +48 -0
  69. package/src/components/common/Tabs.vue +129 -0
  70. package/src/components/common/Tag.vue +53 -0
  71. package/src/components/common/Tooltip.vue +49 -0
  72. package/src/components/common/VerticalTabs.vue +34 -0
  73. package/src/components/common/card/CardItem.vue +27 -0
  74. package/src/components/common/card/CardItemGroup.vue +45 -0
  75. package/src/components/common/facet/Leaf.vue +97 -0
  76. package/src/components/common/facet/TriState.vue +37 -0
  77. package/src/components/common/table/TableData.vue +48 -0
  78. package/src/components/common/table/TableHeader.vue +21 -0
  79. package/src/components/dialogs/ChooseValueDialog.vue +97 -0
  80. package/src/components/dialogs/ConfirmDialog.vue +73 -0
  81. package/src/components/dialogs/CopyDialog.vue +51 -0
  82. package/src/components/dialogs/DownloadDialog.vue +48 -0
  83. package/src/components/dialogs/NameDescDialog.vue +74 -0
  84. package/src/components/dialogs/NameDialog.vue +56 -0
  85. package/src/components/dialogs/PopupEditor.vue +113 -0
  86. package/src/components/dialogs/ProgressDialog.vue +58 -0
  87. package/src/components/dialogs/ResetPasswordDialog.vue +58 -0
  88. package/src/components/dialogs/Wizard.vue +99 -0
  89. package/src/components/dialogs/wizard/Stepper.vue +31 -0
  90. package/src/components/form/CheckBox.vue +26 -0
  91. package/src/components/form/Editor.vue +93 -0
  92. package/src/components/form/FormCol.vue +19 -0
  93. package/src/components/form/FormRow.vue +19 -0
  94. package/src/components/form/FormSection.vue +21 -0
  95. package/src/components/form/GreyForm.vue +7 -0
  96. package/src/components/form/GreyInput.vue +51 -0
  97. package/src/components/form/GreyInputAutocomplete.vue +100 -0
  98. package/src/components/form/GreyInputCopy.vue +66 -0
  99. package/src/components/form/GreyInputGrow.vue +42 -0
  100. package/src/components/form/GreyInputToken.vue +78 -0
  101. package/src/components/form/GreyPassword.vue +36 -0
  102. package/src/components/form/GreySelect.vue +154 -0
  103. package/src/components/form/GreySelectInput.vue +123 -0
  104. package/src/components/form/GreySelectInputMultiple.vue +218 -0
  105. package/src/components/form/GreyTel.vue +58 -0
  106. package/src/components/form/HamburgerItem.vue +95 -0
  107. package/src/components/form/KeyValueEntry.vue +74 -0
  108. package/src/components/form/RadioInput.vue +38 -0
  109. package/src/components/form/UploadFile.vue +99 -0
  110. package/src/components/icons/AiIcon.vue +6 -0
  111. package/src/components/icons/GithubIcon.vue +18 -0
  112. package/src/components/icons/HighPriorityIcon.vue +6 -0
  113. package/src/components/icons/PowerOffIcon.vue +6 -0
  114. package/src/components/icons/SaveIcon.vue +6 -0
  115. package/src/components/index.js +134 -0
  116. package/src/components/menu/DialogMenu.vue +142 -0
  117. package/src/components/menu/GrandChild.vue +39 -0
  118. package/src/components/menu/GridMenu.vue +88 -0
  119. package/src/components/menu/MenuAvatar.vue +66 -0
  120. package/src/components/menu/MenuDesktop.vue +90 -0
  121. package/src/components/notifications/Notify.vue +123 -0
  122. package/src/components/notifications/NotifyList.vue +130 -0
  123. package/src/components/page-structure/FacetPage.vue +77 -0
  124. package/src/components/query/Child.vue +63 -0
  125. package/src/components/query/LVDBQuery.vue +38 -0
  126. package/src/components/status/Active.vue +44 -0
  127. package/src/components/status/ScoreLevel.vue +43 -0
  128. package/src/components/status/Status.vue +51 -0
  129. package/src/components/status/TaskDot.vue +25 -0
  130. package/src/components/status/TaskStatus.vue +26 -0
  131. package/src/components/status/TicketStatus.vue +201 -0
  132. package/src/components/status/Trend.vue +20 -0
  133. package/src/components/tables/ArgumentRunTable.vue +96 -0
  134. package/src/components/tables/ArgumentTable.vue +67 -0
  135. package/src/components/tables/CloudFormationParameters.vue +25 -0
  136. package/src/constants/colors.js +248 -0
  137. package/src/constants/font-map.js +128 -0
  138. package/src/constants/fpl2.js +162 -0
  139. package/src/constants/icon-svg.js +405 -0
  140. package/src/constants/schedule.js +52 -0
  141. package/src/fpl/AddPanel.vue +237 -0
  142. package/src/fpl/Configs/Alert.vue +16 -0
  143. package/src/fpl/Configs/AlertSprite.vue +2 -0
  144. package/src/fpl/Configs/Chart.vue +63 -0
  145. package/src/fpl/Configs/Config.js +154 -0
  146. package/src/fpl/Configs/Counter.vue +35 -0
  147. package/src/fpl/Configs/Histogram.vue +70 -0
  148. package/src/fpl/Configs/IPMap.vue +37 -0
  149. package/src/fpl/Configs/Image.vue +163 -0
  150. package/src/fpl/Configs/MetricChart.vue +20 -0
  151. package/src/fpl/Configs/PieChart.vue +37 -0
  152. package/src/fpl/Configs/SparkChart.vue +41 -0
  153. package/src/fpl/Configs/StackedBarChart.vue +49 -0
  154. package/src/fpl/Configs/Table.vue +211 -0
  155. package/src/fpl/Configs/Text.vue +14 -0
  156. package/src/fpl/Configs/TopNChart.vue +37 -0
  157. package/src/fpl/Outputs/FPLAlert.vue +64 -0
  158. package/src/fpl/Outputs/FPLStream.vue +41 -0
  159. package/src/fpl/Outputs/FPLTable.vue +77 -0
  160. package/src/fpl/Panel.vue +202 -0
  161. package/src/fpl/Panels/Alert.vue +85 -0
  162. package/src/fpl/Panels/AlertSprite.vue +9 -0
  163. package/src/fpl/Panels/Chart.vue +98 -0
  164. package/src/fpl/Panels/Counter.vue +43 -0
  165. package/src/fpl/Panels/Histogram.vue +138 -0
  166. package/src/fpl/Panels/IPMap.vue +48 -0
  167. package/src/fpl/Panels/Image.vue +35 -0
  168. package/src/fpl/Panels/MetricChart.vue +97 -0
  169. package/src/fpl/Panels/PieChart.vue +54 -0
  170. package/src/fpl/Panels/SparkChart.vue +166 -0
  171. package/src/fpl/Panels/StackedBarChart.vue +74 -0
  172. package/src/fpl/Panels/Table.vue +103 -0
  173. package/src/fpl/Panels/Text.vue +24 -0
  174. package/src/fpl/Panels/TopNChart.vue +69 -0
  175. package/src/fpl/index.js +39 -0
  176. package/src/utils/download.js +220 -0
  177. package/src/utils/formatOutput.js +156 -0
  178. package/src/utils/random.js +32 -0
  179. package/src/utils/timeUtils.js +138 -0
@@ -0,0 +1,293 @@
1
+ <template>
2
+ <div :id="id" class="float-left">
3
+ <div :id="id + 'tooltip'" role="tooltip" class="tooltip"></div>
4
+ </div>
5
+ <div class="overflow-auto" :style="`width: ${width}px; overflow: auto`">
6
+ <div :id="id + 'legend'"></div>
7
+ </div>
8
+ </template>
9
+ <script>
10
+ import * as d3 from "d3";
11
+ import { chartColors } from "@/constants/colors";
12
+ import { humanCount, dataCount } from "@/utils/formatOutput";
13
+ import { adjustText } from "@/constants/font-map";
14
+
15
+ export default {
16
+ props: {
17
+ id: {
18
+ type: String,
19
+ required: true,
20
+ },
21
+ data: {
22
+ type: Array,
23
+ required: true,
24
+ },
25
+ unit: {
26
+ type: String,
27
+ default: "Count",
28
+ },
29
+ width: {
30
+ type: Number,
31
+ default: 350,
32
+ },
33
+ height: {
34
+ type: Number,
35
+ default: 200,
36
+ },
37
+ tooltipOffset: {
38
+ type: String,
39
+ default: "layer",
40
+ },
41
+ valueName: {
42
+ type: String,
43
+ default: "Value",
44
+ },
45
+ theme: {
46
+ type: String,
47
+ default: "light",
48
+ },
49
+ },
50
+ data() {
51
+ return {
52
+ svg: null,
53
+ legend: null,
54
+ };
55
+ },
56
+ mounted() {
57
+ this.initializeChart();
58
+ this.createChart();
59
+ },
60
+ methods: {
61
+ initializeChart() {
62
+ this.svg = d3
63
+ .select("#" + this.id)
64
+ .append("svg")
65
+ .attr("width", this.width)
66
+ .attr("height", this.height - 10);
67
+ },
68
+ createChart() {
69
+ // Declare the chart dimensions and margins.
70
+ const width = this.width;
71
+ const height = this.height - 20;
72
+ const maxRadius = Math.min(width, height) / 2;
73
+ const radius =
74
+ maxRadius * 2 + 100 > width
75
+ ? maxRadius > 150
76
+ ? maxRadius - 75
77
+ : maxRadius - 50
78
+ : maxRadius;
79
+ const fieldMap = {};
80
+ this.data.forEach((d, i) => {
81
+ fieldMap[d.field] = i;
82
+ });
83
+ const pie = d3.pie().value((d) => d.values);
84
+ const arc = d3.arc().innerRadius(0).outerRadius(radius);
85
+ const outerArc = d3
86
+ .arc()
87
+ .innerRadius(radius * 0.9)
88
+ .outerRadius(radius * 0.9);
89
+
90
+ const mouseover = (event, d) => {
91
+ const y =
92
+ !event.target.id || event.target.id.endsWith("dots")
93
+ ? height / 2
94
+ : event[this.tooltipOffset + "Y"];
95
+ const x =
96
+ !event.target.id || event.target.id.endsWith("dots")
97
+ ? 0
98
+ : event[this.tooltipOffset + "X"];
99
+ const index = fieldMap[d.data.field];
100
+ const value =
101
+ this.unit === "Bytes (B)" || this.unit === "B"
102
+ ? dataCount(d.data.values) + "B"
103
+ : this.unit === "Percent (%)"
104
+ ? d.data.values.toFixed(2) + "%"
105
+ : humanCount(d.data.values);
106
+ d3.selectAll("." + this.id + "pie").style("opacity", 0.4);
107
+ d3.select("#" + this.id + index + "pie").style("opacity", 1);
108
+ d3.selectAll("." + this.id + "labels").style("opacity", 0.4);
109
+ d3.select("#" + this.id + index + "labels").style("opacity", 1);
110
+ d3.select("#" + this.id + index + "polyline").style("opacity", 1);
111
+ d3.select("#" + this.id + "tooltip")
112
+ .html(
113
+ `${d.data.field}<br>${this.valueName}: ${value} (${(
114
+ ((d.endAngle - d.startAngle) / (2 * Math.PI)) *
115
+ 100
116
+ ).toFixed(2)}%)`
117
+ )
118
+ .style("opacity", 1)
119
+ .style("left", x + 10 + "px")
120
+ .style("top", y + "px");
121
+ };
122
+ const mouseout = () => {
123
+ d3.selectAll("." + this.id + "pie").style("opacity", 0.8);
124
+ d3.selectAll("." + this.id + "labels").style("opacity", 1);
125
+ d3.select("#" + this.id + "tooltip")
126
+ .style("opacity", 0)
127
+ .style("left", "0px")
128
+ .style("top", "0px");
129
+ };
130
+
131
+ const pieData = pie(this.data);
132
+ const total = pieData.reduce((acc, d) => acc + d.data.values, 0);
133
+ const ratio = width / height;
134
+ const textWidth = ratio > 2 ? (ratio > 2.5 ? 1500 : 900) : 600;
135
+
136
+ const resolveOverlaps = (data) => {
137
+ const spacing = radius < 100 ? 12 : 14;
138
+ return data.map((d, i) => {
139
+ if (i === 0) {
140
+ return d;
141
+ }
142
+ if (!total) {
143
+ const diff = data[i - 1].pos[1] - d.pos[1] + spacing;
144
+ d.pos[1] += diff;
145
+ return d;
146
+ }
147
+ // check if the previous label is on the opposite side of the circle
148
+ const previosMidpoint =
149
+ (data[i - 1].startAngle + data[i - 1].endAngle) / 2;
150
+ const currentMidpoint = (d.startAngle + d.endAngle) / 2;
151
+ if (previosMidpoint < Math.PI && currentMidpoint > Math.PI) {
152
+ // current is left side but previous is right side
153
+ return d;
154
+ } else if (previosMidpoint > Math.PI && currentMidpoint < Math.PI) {
155
+ // current is right side but previous is left side
156
+ return d;
157
+ }
158
+ if (currentMidpoint > Math.PI) {
159
+ const diff = data[i - 1].pos[1] - d.pos[1] + spacing;
160
+ if (diff > 0) {
161
+ d.pos[1] += diff;
162
+ }
163
+ } else {
164
+ const diff = d.pos[1] - data[i - 1].pos[1] + spacing;
165
+ if (diff > 0) {
166
+ d.pos[1] -= diff;
167
+ }
168
+ }
169
+ return d;
170
+ });
171
+ };
172
+ const adjustedPieData = resolveOverlaps(
173
+ pieData
174
+ .map((d) => {
175
+ if (!total) {
176
+ return {
177
+ ...d,
178
+ pos: outerArc.centroid({
179
+ startAngle: 2 * Math.PI,
180
+ endAngle: 2 * Math.PI,
181
+ }),
182
+ };
183
+ }
184
+ return { ...d, pos: outerArc.centroid(d) };
185
+ })
186
+ .sort((a, b) => b.startAngle - a.startAngle)
187
+ );
188
+
189
+ const svg = this.svg;
190
+ const handle = this;
191
+ svg
192
+ .selectAll("g")
193
+ .data(adjustedPieData)
194
+ .join(
195
+ (enter) => enterChart(enter),
196
+ (update) => enterChart(update),
197
+ (exit) => exitChart(exit)
198
+ );
199
+
200
+ function enterChart(enter) {
201
+ const slices = enter.append("g");
202
+ const polylines = enter.append("g");
203
+
204
+ slices
205
+ .append("path")
206
+ .attr("class", handle.id + "pie")
207
+ .attr("id", (d) => handle.id + fieldMap[d.data.field] + "pie")
208
+ .attr("transform", `translate(${width / 2},${height / 2 + 10})`)
209
+ .attr("d", (d) => {
210
+ if (!total) {
211
+ d.endAngle = Math.PI * pieData.length;
212
+ return arc(d);
213
+ }
214
+ return arc(d);
215
+ })
216
+ .attr("fill", (d, i) =>
217
+ !total ? chartColors[0] : chartColors[i % chartColors.length]
218
+ )
219
+ .style("opacity", 0.8)
220
+ .style("fill-opacity", 0)
221
+ .on("mouseover", mouseover)
222
+ .on("mouseout", mouseout)
223
+ .transition()
224
+ .duration(800)
225
+ .attrTween("d", function (d) {
226
+ const interpolate = d3.interpolate(handle._current, d);
227
+ handle._current = interpolate(1);
228
+ return (t) => arc(interpolate(t));
229
+ })
230
+ .style("fill-opacity", 1);
231
+
232
+ polylines
233
+ .append("polyline")
234
+ .attr("class", handle.id + "labels")
235
+ .attr("id", (d) => handle.id + fieldMap[d.data.field] + "polyline")
236
+ .attr("points", (d) => {
237
+ const pos = d.pos;
238
+ const midAngle = (d.startAngle + d.endAngle) / 2;
239
+ const x = midAngle < Math.PI ? radius * 1.1 : -radius * 1.1;
240
+ if (!total) {
241
+ const x = -radius * 1.1;
242
+ return [
243
+ arc.centroid({ startAngle: 0, endAngle: 0 }),
244
+ outerArc.centroid({ startAngle: 0, endAngle: 0 }),
245
+ [x, pos[1]],
246
+ ];
247
+ }
248
+ return [arc.centroid(d), outerArc.centroid(d), [x, pos[1]]];
249
+ })
250
+ .attr("fill", "none")
251
+ .style("stroke", handle.theme === "dark" ? "white" : "black")
252
+ .attr("transform", `translate(${width / 2},${height / 2})`)
253
+ .style("opacity", 0)
254
+ .transition()
255
+ .duration(800)
256
+ .style("opacity", 1);
257
+
258
+ polylines
259
+ .append("text")
260
+ .attr("class", handle.id + "labels")
261
+ .attr("id", (d) => handle.id + fieldMap[d.data.field] + "labels")
262
+ .attr("transform", (d) => {
263
+ const pos = d.pos;
264
+ const midAngle = (d.startAngle + d.endAngle) / 2;
265
+ const x = midAngle < Math.PI ? radius * 1.15 : -radius * 1.15;
266
+ return `translate(${x + width / 2},${pos[1] + height / 2})`;
267
+ })
268
+ .attr("text-anchor", (d) => {
269
+ const midAngle = (d.startAngle + d.endAngle) / 2;
270
+ return midAngle < Math.PI ? "start" : "end";
271
+ })
272
+ .attr("font-size", radius < 100 ? "9px" : "11px")
273
+ .style("fill", handle.theme === "dark" ? "white" : "black")
274
+ .text((d) => {
275
+ if (d.data.field === 0) return 0;
276
+ if (!d.data.field) return "(no name)";
277
+ return adjustText(d.data.field, textWidth);
278
+ })
279
+ .on("mouseover", mouseover)
280
+ .on("mouseout", mouseout)
281
+ .style("opacity", 0)
282
+ .transition()
283
+ .duration(1200)
284
+ .style("opacity", 1);
285
+ }
286
+
287
+ function exitChart(exit) {
288
+ exit.call((g) => g.style("opacity", 0).remove());
289
+ }
290
+ },
291
+ },
292
+ };
293
+ </script>
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <div :id="id" class="float-left" />
3
+ </template>
4
+ <script>
5
+ import * as d3 from "d3";
6
+ import { colors } from "@/constants/colors";
7
+
8
+ export default {
9
+ props: {
10
+ id: {
11
+ type: String,
12
+ required: true,
13
+ },
14
+ data: {
15
+ type: Object,
16
+ required: true,
17
+ },
18
+ width: {
19
+ type: Number,
20
+ default: 350,
21
+ },
22
+ height: {
23
+ type: Number,
24
+ default: 200,
25
+ },
26
+ theme: {
27
+ type: String,
28
+ default: "light",
29
+ },
30
+ },
31
+ data() {
32
+ return {
33
+ svg: null,
34
+ legend: null,
35
+ };
36
+ },
37
+ mounted() {
38
+ this.initializeChart();
39
+ this.createChart();
40
+ },
41
+ methods: {
42
+ initializeChart() {
43
+ this.svg = d3
44
+ .select("#" + this.id)
45
+ .append("svg")
46
+ .attr("width", this.width)
47
+ .attr("height", this.height);
48
+ },
49
+ createChart() {
50
+ const width = this.width;
51
+ const height = this.height;
52
+ const radius = Math.min(width, height) / 2;
53
+ const progress = this.data.progress;
54
+
55
+ const arc = d3
56
+ .arc()
57
+ .innerRadius(radius * 0.7)
58
+ .outerRadius(radius)
59
+ .startAngle(0);
60
+
61
+ this.svg
62
+ .append("path")
63
+ .datum({ endAngle: 2 * Math.PI })
64
+ .attr("d", arc)
65
+ .attr("fill", colors[this.theme].canvas)
66
+ .attr("transform", `translate(${width / 2},${height / 2})`);
67
+
68
+ this.svg
69
+ .append("path")
70
+ .datum({ endAngle: 0 })
71
+ .attr("d", arc)
72
+ .attr("fill", colors[this.theme].secondary)
73
+ .attr("transform", `translate(${width / 2},${height / 2})`)
74
+ .transition()
75
+ .duration(1000)
76
+ .call((transition) =>
77
+ transition.attrTween("d", (d) => {
78
+ const interpolate = d3.interpolate(0, progress * 2 * Math.PI);
79
+ return (t) => {
80
+ d.endAngle = interpolate(t);
81
+ return arc(d);
82
+ };
83
+ })
84
+ );
85
+
86
+ // Add text
87
+ this.svg
88
+ .append("text")
89
+ .attr("text-anchor", "middle")
90
+ .attr("dy", "0.35em")
91
+ .style("font-size", "35px")
92
+ .text("0%")
93
+ .style("fill", colors[this.theme].text)
94
+ .attr("transform", `translate(${width / 2},${height / 2})`)
95
+ .transition()
96
+ .duration(1000)
97
+ .tween("text", function () {
98
+ const interpolate = d3.interpolate(0, progress * 100);
99
+ return function (t) {
100
+ this.textContent = `${Math.round(interpolate(t))}%`;
101
+ };
102
+ });
103
+ },
104
+ },
105
+ };
106
+ </script>