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