|
1 | 1 | <script setup lang="ts"> |
2 | | -import { computed, ref } from 'vue'; |
3 | | -
|
4 | 2 | import 'devextreme/dist/css/dx.material.blue.light.compact.css'; |
5 | | -import DxButton from 'devextreme-vue/button'; |
| 3 | +import DxChart, { DxBackgroundColor, DxCommonPaneSettings, DxConstantLine, DxLabel, DxSeries, DxTooltip, DxValueAxis } from 'devextreme-vue/chart'; |
| 4 | +import { registerGradient } from 'devextreme-vue/common/charts'; |
| 5 | +import { formatNumber } from 'devextreme/localization'; |
6 | 6 |
|
7 | | -const props = defineProps({ |
8 | | - text: String, |
9 | | -}); |
10 | | -const count = ref(0); |
11 | | -const buttonText = computed<string>( |
12 | | - () => `Click ${props.text}: ${count.value}` |
13 | | -); |
14 | | -function clickHandler() { |
15 | | - count.value += 1; |
| 7 | +const chartData = [ |
| 8 | + { month: 'January', targetSpend: 12000, actualSpend: 9500 }, |
| 9 | + { month: 'February', targetSpend: 15500, actualSpend: 16500 }, |
| 10 | + { month: 'March', targetSpend: 13500, actualSpend: 12000 }, |
| 11 | + { month: 'April', targetSpend: 16000, actualSpend: 14000 }, |
| 12 | + { month: 'May', targetSpend: 17000, actualSpend: 18500 }, |
| 13 | + { month: 'June', targetSpend: 20000, actualSpend: 17500 }, |
| 14 | + { month: 'July', targetSpend: 14500, actualSpend: 11000 }, |
| 15 | + { month: 'August', targetSpend: 21000, actualSpend: 22500 }, |
| 16 | + { month: 'September', targetSpend: 19000, actualSpend: 18000 }, |
| 17 | + { month: 'October', targetSpend: 22000, actualSpend: 25000 }, |
| 18 | + { month: 'November', targetSpend: 16000, actualSpend: 14500 }, |
| 19 | + { month: 'December', targetSpend: 25000, actualSpend: 27000 }, |
| 20 | +]; |
| 21 | +
|
| 22 | +function calculateAverageSpend() { |
| 23 | + let sum = 0; |
| 24 | +
|
| 25 | + chartData.forEach((data) => { |
| 26 | + sum += data.actualSpend; |
| 27 | + }); |
| 28 | +
|
| 29 | + return sum / chartData.length; |
16 | 30 | } |
| 31 | +
|
| 32 | +function customizeTooltip(data: { value: number }) { |
| 33 | + const isValueAboveAverage = data.value > calculateAverageSpend(); |
| 34 | + const aboveText = `${formatNumber(data.value, 'currency')}\n${formatNumber(data.value - calculateAverageSpend(), 'currency')} above average spending.`; |
| 35 | + const belowText = `${formatNumber(data.value, 'currency')}\n${formatNumber(calculateAverageSpend() - data.value, 'currency')} below average spending.`; |
| 36 | + return { text: isValueAboveAverage ? aboveText : belowText }; |
| 37 | +} |
| 38 | +
|
| 39 | +const chartGradient = registerGradient('linear', { |
| 40 | + colors: [{ |
| 41 | + offset: '20%', |
| 42 | + color: '#dee4ff', |
| 43 | + }, { |
| 44 | + offset: '90%', |
| 45 | + color: '#ffdeff', |
| 46 | + }], |
| 47 | +}); |
17 | 48 | </script> |
18 | 49 | <template> |
19 | 50 | <div> |
20 | | - <DxButton |
21 | | - :text="buttonText" |
22 | | - @click="clickHandler" |
23 | | - /> |
| 51 | + <DxChart |
| 52 | + title="Target vs Actual Spending 2024" |
| 53 | + :data-source="chartData" |
| 54 | + > |
| 55 | + <DxSeries |
| 56 | + type="bar" |
| 57 | + argument-field="month" |
| 58 | + value-field="targetSpend" |
| 59 | + name="Budget" |
| 60 | + color="#5996ff" |
| 61 | + /> |
| 62 | + <DxSeries |
| 63 | + type="spline" |
| 64 | + argument-field="month" |
| 65 | + value-field="actualSpend" |
| 66 | + name="Amount Spend" |
| 67 | + color="#cb4bfa" |
| 68 | + /> |
| 69 | + <DxValueAxis> |
| 70 | + <DxConstantLine |
| 71 | + :value="calculateAverageSpend()" |
| 72 | + color="#0000c7" |
| 73 | + > |
| 74 | + <DxLabel |
| 75 | + text="Yearly Spend Average" |
| 76 | + /> |
| 77 | + </DxConstantLine> |
| 78 | + </DxValueAxis> |
| 79 | + <DxTooltip |
| 80 | + :enabled="true" |
| 81 | + :customize-tooltip="customizeTooltip" |
| 82 | + /> |
| 83 | + <DxCommonPaneSettings> |
| 84 | + <DxBackgroundColor |
| 85 | + base="#ffffff" |
| 86 | + :fill-id="chartGradient" |
| 87 | + /> |
| 88 | + </DxCommonPaneSettings> |
| 89 | + </DxChart> |
24 | 90 | </div> |
25 | 91 | </template> |
0 commit comments