@carbon/vue 1.0.2 → 1.1.3

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 (89) hide show
  1. package/CHANGELOG.md +192 -0
  2. package/README.md +156 -211
  3. package/dist/carbon-vue.common.js +10567 -12509
  4. package/dist/carbon-vue.common.js.map +1 -1
  5. package/dist/carbon-vue.umd.js +10567 -12509
  6. package/dist/carbon-vue.umd.js.map +1 -1
  7. package/dist/carbon-vue.umd.min.js +31 -7
  8. package/dist/carbon-vue.umd.min.js.map +1 -1
  9. package/dist/demo.html +2 -2
  10. package/package.json +17 -157
  11. package/src/components/cv-accordion/_cv-accordion-item-skeleton.vue +3 -13
  12. package/src/components/cv-accordion/cv-accordion-item.vue +2 -9
  13. package/src/components/cv-breadcrumb/cv-breadcrumb-item.vue +3 -1
  14. package/src/components/cv-button/cv-button-skeleton.vue +1 -6
  15. package/src/components/cv-button/cv-button.vue +15 -37
  16. package/src/components/cv-checkbox/cv-checkbox.vue +42 -26
  17. package/src/components/cv-code-snippet/_cv-code-snippet-multiline.vue +13 -23
  18. package/src/components/cv-code-snippet/_cv-code-snippet-oneline.vue +11 -5
  19. package/src/components/cv-code-snippet/_cv-feedback-button.vue +1 -3
  20. package/src/components/cv-code-snippet/cv-code-snippet.vue +2 -7
  21. package/src/components/cv-content-switcher/cv-content-switcher-button.vue +20 -4
  22. package/src/components/cv-content-switcher/cv-content-switcher.vue +3 -10
  23. package/src/components/cv-data-table/cv-data-table-row.vue +15 -11
  24. package/src/components/cv-data-table/cv-data-table.vue +30 -28
  25. package/src/components/cv-date-picker/cv-date-picker.vue +53 -47
  26. package/src/components/cv-dropdown/_cv-dropdown-inner-c10.vue +226 -0
  27. package/src/components/cv-dropdown/_cv-dropdown-inner.vue +201 -0
  28. package/src/components/cv-dropdown/cv-dropdown-item.vue +6 -8
  29. package/src/components/cv-dropdown/cv-dropdown-skeleton.vue +1 -5
  30. package/src/components/cv-dropdown/cv-dropdown.vue +22 -169
  31. package/src/components/cv-file-uploader/cv-file-uploader.vue +44 -22
  32. package/src/components/cv-inline-loading/cv-inline-loading.vue +37 -0
  33. package/src/components/cv-inline-notification/cv-inline-notification.vue +22 -19
  34. package/src/components/cv-link/cv-link.vue +1 -6
  35. package/src/components/cv-loading/cv-loading.vue +13 -4
  36. package/src/components/cv-modal/cv-modal.vue +17 -15
  37. package/src/components/cv-number-input/cv-number-input.vue +20 -32
  38. package/src/components/cv-overflow-menu/cv-overflow-menu.vue +13 -19
  39. package/src/components/cv-pagination/cv-pagination.vue +61 -42
  40. package/src/components/cv-progress/_cv-progress-step-complete.vue +3 -12
  41. package/src/components/cv-progress/cv-progress-step.vue +97 -0
  42. package/src/components/cv-progress/cv-progress.vue +68 -13
  43. package/src/components/cv-radio-button/cv-radio-button.vue +1 -0
  44. package/src/components/cv-search/cv-search.vue +144 -15
  45. package/src/components/cv-select/cv-select-option.vue +3 -1
  46. package/src/components/cv-select/cv-select.vue +147 -15
  47. package/src/components/cv-slider/cv-slider.vue +14 -43
  48. package/src/components/cv-structured-list/_cv-structured-list-item-selectable.vue +18 -6
  49. package/src/components/cv-structured-list/cv-structured-list-item.vue +1 -3
  50. package/src/components/cv-structured-list/cv-structured-list.vue +10 -2
  51. package/src/components/cv-tabs/cv-tabs.vue +31 -15
  52. package/src/components/cv-tag/cv-tag.vue +23 -13
  53. package/src/components/cv-text-area/cv-text-area.vue +23 -10
  54. package/src/components/cv-text-input/cv-text-input.vue +80 -10
  55. package/src/components/cv-tile/_cv-tile-clickable.vue +1 -5
  56. package/src/components/cv-tile/_cv-tile-expandable.vue +11 -15
  57. package/src/components/cv-tile/_cv-tile-selectable.vue +14 -3
  58. package/src/components/cv-tile/cv-tile.vue +1 -4
  59. package/src/components/cv-time-picker/cv-time-picker.vue +27 -29
  60. package/src/components/cv-toast-notification/cv-toast-notification.vue +32 -6
  61. package/src/components/cv-toggle/cv-toggle.vue +3 -7
  62. package/src/components/cv-toolbar/cv-toolbar-option.vue +1 -4
  63. package/src/components/cv-toolbar/cv-toolbar-search.vue +5 -0
  64. package/src/components/cv-tooltip/cv-definition-tooltip.vue +1 -3
  65. package/src/components/cv-tooltip/cv-interactive-tooltip.vue +13 -28
  66. package/src/components/cv-tooltip/cv-tooltip.vue +11 -15
  67. package/src/components/cv-wrapper/_cv-wrapper.js +33 -0
  68. package/src/index-components-vue.js +1 -3
  69. package/src/index.js +1 -5
  70. package/src/{_internal/_feature-flags.js → internal/feature-flags.js} +30 -2
  71. package/dist/carbon-data-viz-vue.common.js +0 -23907
  72. package/dist/carbon-data-viz-vue.common.js.map +0 -1
  73. package/dist/carbon-data-viz-vue.css +0 -1
  74. package/dist/carbon-data-viz-vue.umd.js +0 -23917
  75. package/dist/carbon-data-viz-vue.umd.js.map +0 -1
  76. package/dist/carbon-data-viz-vue.umd.min.js +0 -2
  77. package/dist/carbon-data-viz-vue.umd.min.js.map +0 -1
  78. package/src/assets/styles/_carbon-helpers.scss +0 -8
  79. package/src/components/cv-checkbox/_cv-checkbox-inner-form-item.vue +0 -19
  80. package/src/components/cv-checkbox/_cv-checkbox-inner.vue +0 -59
  81. package/src/components/cv-progress/_cv-progress-step.vue +0 -51
  82. package/src/components/cv-search/_cv-search-inner-form-item.vue +0 -22
  83. package/src/components/cv-search/_cv-search-inner.vue +0 -162
  84. package/src/components/cv-select/_cv-select-inner-form-item.vue +0 -22
  85. package/src/components/cv-select/_cv-select-inner.vue +0 -78
  86. package/src/data-viz/cv-bar-graph/cv-bar-graph.vue +0 -495
  87. package/src/data-viz/cv-gauge/cv-gauge.vue +0 -196
  88. package/src/data-viz/cv-pie-chart/cv-pie-chart.vue +0 -194
  89. package/src/index-data-viz.js +0 -29
@@ -1,495 +0,0 @@
1
- <template>
2
- <div class="cv-bar-graph" :class="{ 'cv-bar-graph--empty': noData }">
3
- <svg class="cv-bar-graph__svg" ref="svg">
4
- <g class="cv-bar-graph__root" ref="root">
5
- <g class="cv-bar-graph__x-axis" ref="xAxis">
6
- <text class="cv-bar-graph__x-axis-label" ref="xAxisLabel"></text>
7
- </g>
8
- <g class="cv-bar-graph__y-axis" ref="yAxis">
9
- <text class="cv-bar-graph__y-axis-label" ref="yAxisLabel"></text>
10
- </g>
11
- </g>
12
- </svg>
13
- <div class="cv-bar-graph__key" v-if="keyLabels" ref="key">
14
- <span class="cv-bar-graph__key-title">Key</span>
15
- <div
16
- class="cv-bar-graph__key-entry"
17
- v-for="(keyLabel, i) in keyLabels"
18
- :key="keyLabel"
19
- >
20
- <div
21
- class="cv-bar-graph__key-entry-swatch"
22
- :style="{ background: colors(i) }"
23
- ></div>
24
- {{ keyLabel }}
25
- </div>
26
- </div>
27
- <div class="cv-bar-graph__empty-content" ref="emptyContent">
28
- <div class="cv-bar-graph__empty-content-inner">
29
- <slot name="emptyContent">{{ emptyText }}</slot>
30
- </div>
31
- </div>
32
- <div class="cv-bar-graph__tooltip" ref="tooltip"></div>
33
- </div>
34
- </template>
35
-
36
- <script>
37
- import * as d3 from 'd3';
38
- import 'd3-transition';
39
-
40
- const axisOffset = 16;
41
- const numYAxisTicksHint = 4;
42
-
43
- export default {
44
- name: 'CvBarGraph',
45
- props: {
46
- data: { type: Array, required: true },
47
- keyLabels: Array,
48
- emptyText: String,
49
- width: { type: Number, default: 800 },
50
- height: { type: Number, default: 300 },
51
- margins: {
52
- type: Object,
53
- default: () => {
54
- return { top: 30, right: 20, bottom: 70, left: 65 };
55
- },
56
- },
57
- barColors: {
58
- type: Array,
59
- default: () => ['#00a78f', '#3b1a40', '#473793', '#3c6df0', '#56d2bb'],
60
- },
61
- yAxisFormat: String,
62
- xAxisTimeFormat: String,
63
- xAxisLabel: String,
64
- yAxisLabel: String,
65
- xAxisLabelOffset: { type: Number, default: 50 },
66
- yAxisLabelOffset: { type: Number, default: 50 },
67
- yAxisGridLines: { type: Boolean, default: true },
68
- },
69
- data() {
70
- return {
71
- xScale: d3.scaleBand(),
72
- xSubScale: d3.scaleBand(),
73
- yScale: d3.scaleLinear(),
74
- };
75
- },
76
- computed: {
77
- colors() {
78
- return d3.scaleOrdinal().range(this.barColors);
79
- },
80
- groupedData() {
81
- let data = this.data;
82
-
83
- if (data.length > 0 && !Array.isArray(data[0].y)) {
84
- data = data.map(value => ({ x: value.x, y: [value.y] }));
85
- }
86
-
87
- return data;
88
- },
89
- noData() {
90
- return this.groupedData.length === 0;
91
- },
92
- plotArea() {
93
- return {
94
- x: this.margins.left,
95
- y: this.margins.top,
96
- width: this.width - (this.margins.left + this.margins.right),
97
- height: this.height - (this.margins.bottom + this.margins.top),
98
- };
99
- },
100
- xAxisGenerator() {
101
- return d3
102
- .axisBottom()
103
- .scale(this.xScale)
104
- .tickSize(0)
105
- .tickFormat(
106
- this.xAxisTimeFormat ? d3.timeFormat(this.xAxisTimeFormat) : null
107
- );
108
- },
109
- yAxisGenerator() {
110
- return d3
111
- .axisLeft()
112
- .scale(this.yScale)
113
- .ticks(numYAxisTicksHint)
114
- .tickSize(-this.plotArea.width)
115
- .tickFormat(this.yAxisFormat ? d3.format(this.yAxisFormat) : null);
116
- },
117
- yScaleMax() {
118
- const max = d3.max(this.groupedData, d => d3.max(d.y));
119
- return max > 0 ? max : 0;
120
- },
121
- yScaleMin() {
122
- const min = d3.min(this.groupedData, d => d3.min(d.y));
123
- return min < 0 ? min : 0;
124
- },
125
- },
126
- methods: {
127
- barHeight(y) {
128
- let barHeight = 0;
129
- if (typeof y === 'number' && !isNaN(y) && isFinite(y)) {
130
- if (y >= 0) {
131
- barHeight = this.yScale(0) - this.yScale(y);
132
- } else {
133
- barHeight = this.yScale(y) - this.yScale(0);
134
- }
135
- }
136
- return barHeight;
137
- },
138
- barYPos(y) {
139
- let barYPos = this.yScale(0);
140
- if (typeof y === 'number' && !isNaN(y) && isFinite(y)) {
141
- if (y >= 0) {
142
- barYPos = this.yScale(y);
143
- }
144
- }
145
- return barYPos;
146
- },
147
- updateGraph() {
148
- const svg = d3.select(this.$refs.svg);
149
- const root = d3.select(this.$refs.root);
150
- const xAxis = d3.select(this.$refs.xAxis);
151
- const yAxis = d3.select(this.$refs.yAxis);
152
- const xAxisLabel = d3.select(this.$refs.xAxisLabel);
153
- const yAxisLabel = d3.select(this.$refs.yAxisLabel);
154
- const key = d3.select(this.$refs.key);
155
- const emptyContent = d3.select(this.$refs.emptyContent);
156
- const tooltip = d3.select(this.$refs.tooltip);
157
-
158
- // Determine how many groups/sets of data are to be plotted.
159
- const numDataGroups = this.noData > 0 ? 0 : this.groupedData[0].y.length;
160
-
161
- // Set up the scales to take account of the plot area size, data ranges
162
- // and inter group and bar paddings.
163
- this.xScale
164
- .rangeRound([0, this.plotArea.width])
165
- .domain(this.groupedData.map(d => d.x))
166
- .paddingOuter(numDataGroups > 1 ? 0 : 0.5)
167
- .paddingInner(numDataGroups > 1 ? 0.3 : 0.5);
168
-
169
- this.xSubScale
170
- .rangeRound([0, this.xScale.bandwidth()])
171
- .domain(d3.range(numDataGroups))
172
- .padding(numDataGroups > 1 ? 0.05 : 0);
173
-
174
- this.yScale
175
- .range([this.plotArea.height, 0])
176
- .domain([this.yScaleMin, this.yScaleMax])
177
- .nice();
178
-
179
- // Set the SVG dimensions and offset the drawing root (top left of the
180
- // plot area) to take the top and left margins into account.
181
- svg.attr('width', this.width).attr('height', this.height);
182
-
183
- root.attr(
184
- 'transform',
185
- `translate(${this.margins.left}, ${this.margins.top})`
186
- );
187
-
188
- // (Re)draw the axes.
189
- const xAxisYPos =
190
- this.yScaleMin >= 0 ? this.plotArea.height : this.plotArea.height + 5;
191
- xAxis
192
- .attr('transform', `translate(0, ${xAxisYPos})`)
193
- .transition()
194
- .duration(500)
195
- .call(this.xAxisGenerator)
196
- .selectAll('.tick text')
197
- .attr('y', axisOffset);
198
-
199
- yAxis
200
- .transition()
201
- .duration(500)
202
- .call(this.yAxisGenerator)
203
- .selectAll('.tick text')
204
- .attr('x', -axisOffset);
205
-
206
- // Make the y-axis gridline for zero solid, rather than dashed.
207
- const yScaleZeroTickIndex = this.yScale
208
- .ticks(numYAxisTicksHint)
209
- .indexOf(0);
210
- yAxis
211
- .selectAll('.tick line')
212
- .attr('visibility', this.yAxisGridLines ? 'visible' : 'hidden')
213
- .filter((d, i) => i === yScaleZeroTickIndex)
214
- .attr('visibility', 'visible')
215
- .attr('stroke-dasharray', 'none');
216
-
217
- // Set up the axis labels.
218
- xAxisLabel
219
- .text(this.xAxisLabel)
220
- .attr(
221
- 'transform',
222
- `translate(${this.plotArea.width / 2}, ${this.xAxisLabelOffset})`
223
- );
224
-
225
- yAxisLabel
226
- .text(this.yAxisLabel)
227
- .attr(
228
- 'transform',
229
- `translate(${-this.yAxisLabelOffset}, ${this.plotArea.height /
230
- 2}) rotate(-90)`
231
- );
232
-
233
- // (Re)draw the bar groups.
234
- let barGroups = root
235
- .selectAll('g.cv-bar-graph__bar-group')
236
- .data(this.groupedData, d => d.x);
237
-
238
- barGroups.exit().remove();
239
-
240
- barGroups = barGroups
241
- .enter()
242
- .append('g')
243
- .attr('class', 'cv-bar-graph__bar-group')
244
- .attr('transform', d => `translate(${this.xScale(d.x)}, 0)`)
245
- .merge(barGroups)
246
- .attr('data-group', d => d.x);
247
-
248
- barGroups
249
- .transition()
250
- .duration(500)
251
- .attr('transform', d => `translate(${this.xScale(d.x)}, 0)`);
252
-
253
- // (Re)draw the bars within the bar groups.
254
- let bars = barGroups
255
- .selectAll('rect')
256
- .data(d => d.y.map((y, i) => ({ x: i, y: y })));
257
-
258
- bars.exit().remove();
259
-
260
- bars = bars
261
- .enter()
262
- .append('rect')
263
- .attr('class', 'cv-bar-graph__bar')
264
- .attr('fill', d => this.colors(d.x))
265
- .attr('y', this.yScale(0))
266
- .attr('height', 0)
267
- .attr('x', d => this.xSubScale(d.x))
268
- .attr('width', this.xSubScale.bandwidth())
269
- .merge(bars)
270
- .on('mouseover', (d, index, nodes) => {
271
- d3.select(nodes[index]).attr('fill', d =>
272
- d3.color(this.colors(d.x)).darker()
273
- );
274
- const format = this.yAxisFormat
275
- ? this.yAxisGenerator.tickFormat()
276
- : this.yScale.tickFormat();
277
- const xPos =
278
- this.margins.left +
279
- this.xScale(nodes[index].parentNode.getAttribute('data-group')) +
280
- this.xSubScale(d.x) +
281
- this.xSubScale.bandwidth() / 2;
282
- const yPos = this.barYPos(d.y) + this.margins.top - 15;
283
- tooltip.text(format(d.y));
284
- tooltip.attr('style', `display:block;top:${yPos}px;left:${xPos}px`);
285
- })
286
- .on('mouseout', (d, index, nodes) => {
287
- d3.select(nodes[index]).attr('fill', d => this.colors(d.x));
288
- tooltip.attr('style', `display:none`);
289
- });
290
-
291
- bars
292
- .transition()
293
- .duration(500)
294
- .attr('fill', d => this.colors(d.x))
295
- .attr('x', d => this.xSubScale(d.x))
296
- .attr('width', this.xSubScale.bandwidth())
297
- .attr('height', d => this.barHeight(d.y))
298
- .attr('y', d => this.barYPos(d.y));
299
-
300
- // Set the position and height of the key (which may or may not be
301
- // visible).
302
- key.attr(
303
- 'style',
304
- `top:${this.margins.top}px; width:${this.margins.right -
305
- 20}px; height:${this.plotArea.height}px;`
306
- );
307
-
308
- // Set the visibility of the empty content overlay and make
309
- // it cover the plot area.
310
- const emptyContentStyle =
311
- (this.noData ? '' : 'display:none;') +
312
- 'top:' +
313
- this.margins.top +
314
- 'px; right:' +
315
- this.margins.right +
316
- 'px; bottom:' +
317
- this.margins.bottom +
318
- 'px; left:' +
319
- this.margins.left +
320
- 'px';
321
- emptyContent.attr('style', emptyContentStyle);
322
- },
323
- },
324
-
325
- mounted() {
326
- console.warn(
327
- `${
328
- this.$vnode.componentOptions.Ctor.extendOptions.name
329
- } - Under review. This component isn't quite ready. Hopefully no features will get broken but this cannot be guarenteed.`
330
- );
331
- this.updateGraph();
332
- },
333
-
334
- watch: {
335
- data() {
336
- this.updateGraph();
337
- },
338
- width() {
339
- this.updateGraph();
340
- },
341
- height() {
342
- this.updateGraph();
343
- },
344
- margins() {
345
- this.updateGraph();
346
- },
347
- barColors() {
348
- this.updateGraph();
349
- },
350
- xAxisTimeFormat() {
351
- this.updateGraph();
352
- },
353
- yAxisFormat() {
354
- this.updateGraph();
355
- },
356
- xAxisLabel() {
357
- this.updateGraph();
358
- },
359
- yAxisLabel() {
360
- this.updateGraph();
361
- },
362
- xAxisLabelOffset() {
363
- this.updateGraph();
364
- },
365
- yAxisLabelOffset() {
366
- this.updateGraph();
367
- },
368
- yAxisGridLines() {
369
- this.updateGraph();
370
- },
371
- },
372
- };
373
- </script>
374
-
375
- <style lang="scss">
376
- @import '../../assets/styles/carbon-helpers';
377
-
378
- $color-text: #5a6872;
379
-
380
- .cv-bar-graph {
381
- display: inline-block;
382
- position: relative;
383
- vertical-align: top;
384
- }
385
-
386
- .cv-bar-graph__svg {
387
- vertical-align: top;
388
- }
389
-
390
- .cv-bar-graph--empty .cv-bar-graph__svg {
391
- opacity: 0.3;
392
- }
393
-
394
- .cv-bar-graph__root {
395
- font-family: 'ibm-plex-sans';
396
- }
397
-
398
- .cv-bar-graph__x-axis,
399
- .cv-bar-graph__y-axis {
400
- font-family: 'ibm-plex-sans';
401
-
402
- .tick line {
403
- stroke: $color-text;
404
- }
405
-
406
- .tick text {
407
- fill: $color-text;
408
- font-size: 10px;
409
- font-weight: 400;
410
- }
411
- }
412
-
413
- .cv-bar-graph__y-axis {
414
- stroke-dasharray: 4;
415
-
416
- path {
417
- display: none;
418
- }
419
- }
420
-
421
- .cv-bar-graph__x-axis-label,
422
- .cv-bar-graph__y-axis-label {
423
- fill: $color-text;
424
- font-size: 10px;
425
- font-weight: 700;
426
- text-anchor: middle;
427
- dominant-baseline: middle;
428
- }
429
-
430
- .cv-bar-graph__empty-content {
431
- display: flex;
432
- position: absolute;
433
- align-items: center;
434
- justify-content: space-around;
435
- text-align: center;
436
- }
437
-
438
- .cv-bar-graph__key {
439
- display: flex;
440
- position: absolute;
441
- right: 0;
442
- flex-direction: column;
443
- padding: 0 10px;
444
- border-left: 1px solid $color-text;
445
- color: $color-text;
446
- }
447
-
448
- .cv-bar-graph--empty .cv-bar-graph__key {
449
- opacity: 0.3;
450
- }
451
-
452
- .cv-bar-graph__key-title {
453
- margin-bottom: 10px;
454
- font-size: 12px;
455
- font-weight: 600;
456
- }
457
-
458
- .cv-bar-graph__key-entry {
459
- margin: 5px 0;
460
- font-size: 10px;
461
- }
462
-
463
- .cv-bar-graph__key-entry-swatch {
464
- display: inline-block;
465
- width: 10px;
466
- height: 10px;
467
- margin-right: 4px;
468
- vertical-align: middle;
469
- }
470
-
471
- .cv-bar-graph__tooltip {
472
- display: none;
473
- position: absolute;
474
- padding: 0.25rem 0.5rem;
475
- transform: translate(-50%, -100%);
476
- border: 1px solid $color__gray-1;
477
- font-weight: 700;
478
- background-color: #fff;
479
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1);
480
- pointer-events: none;
481
-
482
- &:after {
483
- content: '';
484
- position: absolute;
485
- top: 100%;
486
- left: 50%;
487
- width: 0;
488
- height: 0;
489
- transform: translateX(-50%);
490
- border-left: 5px solid transparent;
491
- border-right: 5px solid transparent;
492
- border-top: 5px solid #fff;
493
- }
494
- }
495
- </style>
@@ -1,196 +0,0 @@
1
- <!--
2
- Carbon Style Gauge
3
-
4
- Attributes:
5
- amount: 'x' part of the visualized x/y relationship
6
- total: 'y' part of the visualized x/y relationship
7
- suffix: suffix that will be appended to the amount text and total text in the center of this gauge (optional)
8
- header: text that will appear on top of this gauge (optional)
9
-
10
- Usage:
11
- <cv-gauge :amount="10" :total="100" suffix="GB" header="Example Gauge">
12
- </cv-gauge>
13
-
14
- -->
15
-
16
- <template>
17
- <div class="cv-gauge">
18
- <h1 class="bx--graph-header">{{ header }}</h1>
19
- <div class="cv-gauge__container">
20
- <svg></svg>
21
- <div class="cv-gauge__text">
22
- <p class="cv-gauge__amount"></p>
23
- <p class="cv-gauge__total"></p>
24
- </div>
25
- </div>
26
- </div>
27
- </template>
28
-
29
- <script>
30
- import themeMixin from '../../mixins/theme-mixin';
31
- import * as d3 from 'd3';
32
-
33
- const tau = 2 * Math.PI;
34
- const radius = 80;
35
- const padding = 30;
36
- const boxSize = (radius + padding) * 2;
37
- const arc = d3
38
- .arc()
39
- .innerRadius(radius)
40
- .outerRadius(radius - 10)
41
- .startAngle(0);
42
-
43
- export default {
44
- name: 'CvGauge',
45
- mixins: [themeMixin],
46
- props: {
47
- total: {
48
- type: Number,
49
- },
50
- amount: {
51
- type: Number,
52
- },
53
- suffix: {
54
- type: String,
55
- default: '',
56
- },
57
- header: {
58
- type: String,
59
- default: '',
60
- },
61
- },
62
- data: function() {
63
- return {
64
- g: null,
65
- amountText: null,
66
- totalText: null,
67
- };
68
- },
69
- watch: {
70
- amount: function(newVal) {
71
- this.updateForegroundArc(newVal / this.total);
72
- this.setAmountText(`${newVal}${this.suffix}`);
73
- },
74
- total: function(newVal) {
75
- this.updateForegroundArc(this.amount / newVal);
76
- this.setTotalText(`/${newVal}${this.suffix}`);
77
- },
78
- suffix: function(newVal) {
79
- this.setAmountText(`${this.amount}${newVal}`);
80
- this.setTotalText(`/${this.total}${newVal}`);
81
- },
82
- },
83
- methods: {
84
- // Animation function
85
- arcTween(newAngle) {
86
- return function(d) {
87
- const interpolate = d3.interpolate(d.endAngle, newAngle);
88
- return function(t) {
89
- d.endAngle = interpolate(t);
90
- return arc(d);
91
- };
92
- };
93
- },
94
- setTotalText(val) {
95
- this.totalText
96
- .style('opacity', 0)
97
- .transition()
98
- .duration(1000)
99
- .delay(1700)
100
- .style('opacity', 1)
101
- .text(val);
102
- },
103
- setAmountText(val) {
104
- this.amountText
105
- .style('opacity', 0)
106
- .transition()
107
- .duration(1000)
108
- .delay(1500)
109
- .style('opacity', 1)
110
- .text(val);
111
- },
112
- setForegroundArc(quotient) {
113
- this.g
114
- .append('path')
115
- .datum({ endAngle: 0 })
116
- .style('fill', '#00a68f')
117
- .transition()
118
- .duration(1000)
119
- .delay(1000)
120
- .attrTween('d', this.arcTween(quotient * tau));
121
- },
122
- setBackgroundArc() {
123
- this.g
124
- .append('path')
125
- .datum({ endAngle: tau })
126
- .style('fill', '#dfe3e6')
127
- .attr('d', arc);
128
- },
129
- updateForegroundArc(quotient) {
130
- this.g.selectAll('path:last-of-type').remove();
131
- this.setForegroundArc(quotient);
132
- },
133
- visualizeGauge() {
134
- this.setBackgroundArc();
135
- this.setForegroundArc(this.amount / this.total);
136
- this.setAmountText(`${this.amount}${this.suffix}`);
137
- this.setTotalText(`/${this.total}${this.suffix}`);
138
- },
139
- },
140
- mounted() {
141
- console.warn(
142
- `${
143
- this.$vnode.componentOptions.Ctor.extendOptions.name
144
- } - Under review. This component isn't quite ready. Hopefully no features will get broken but this cannot be guarenteed.`
145
- );
146
-
147
- const svg = d3
148
- .select('svg')
149
- .attr('width', boxSize)
150
- .attr('height', boxSize);
151
- this.g = svg
152
- .append('g')
153
- .attr('transform', `translate(${boxSize / 2}, ${boxSize / 2})`);
154
-
155
- this.amountText = d3.select('.cv-gauge__amount');
156
- this.totalText = d3.select('.cv-gauge__total');
157
- this.visualizeGauge();
158
- },
159
- };
160
- </script>
161
-
162
- <style lang="scss">
163
- .bx--graph-header {
164
- font-weight: 300;
165
- font-size: 24px;
166
- }
167
-
168
- .cv-gauge__container {
169
- position: relative;
170
- width: 220px;
171
- }
172
-
173
- .cv-gauge__text {
174
- position: absolute;
175
- top: 50%;
176
- left: 50%;
177
- transform: translate(-50%, -50%);
178
- text-align: right;
179
- }
180
-
181
- .cv-gauge__amount {
182
- opacity: 0;
183
- font-size: 30px;
184
- font-weight: 300;
185
- }
186
-
187
- .cv-gauge__total {
188
- opacity: 0;
189
- font-size: 14px;
190
- }
191
-
192
- .cv-gauge__amount,
193
- .cv-gauge__total {
194
- margin: 0;
195
- }
196
- </style>