Updated interface, fixed bug
This commit is contained in:
@@ -0,0 +1,133 @@
|
|||||||
|
<script>
|
||||||
|
import Chart from 'chart.js/auto';
|
||||||
|
import {onMount} from 'svelte';
|
||||||
|
import {monthIncome} from "../../../stores.js";
|
||||||
|
import {globalStyles} from "../../../styles.js";
|
||||||
|
|
||||||
|
let ctx;
|
||||||
|
let chartCanvas;
|
||||||
|
let chart = null;
|
||||||
|
|
||||||
|
function groupAndSumByCategory() {
|
||||||
|
const groupedData = new Map();
|
||||||
|
$monthIncome.forEach(income => {
|
||||||
|
const category = income.incomeCategory.name;
|
||||||
|
if (groupedData.has(category)) {
|
||||||
|
groupedData.set(category, groupedData.get(category) + parseInt(income.amount));
|
||||||
|
} else {
|
||||||
|
groupedData.set(category, parseInt(income.amount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Map([...groupedData.entries()].sort());
|
||||||
|
}
|
||||||
|
|
||||||
|
function createGraph() {
|
||||||
|
try {
|
||||||
|
const groupedIncomeData = groupAndSumByCategory();
|
||||||
|
|
||||||
|
const chartLabels = [];
|
||||||
|
const chartValues = [];
|
||||||
|
|
||||||
|
for (const [label, value] of groupedIncomeData.entries()) {
|
||||||
|
chartLabels.push(label);
|
||||||
|
chartValues.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = chartCanvas.getContext('2d');
|
||||||
|
|
||||||
|
if (!chart) {
|
||||||
|
chart = new Chart(ctx, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: chartLabels,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Incomes',
|
||||||
|
data: chartValues
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
backgroundColor: [
|
||||||
|
'rgb(255, 140, 140)',
|
||||||
|
'rgb(140, 180, 255)',
|
||||||
|
'rgb(255, 200, 140)',
|
||||||
|
'rgb(160, 200, 160)',
|
||||||
|
'rgb(160, 130, 200)',
|
||||||
|
'rgb(255, 160, 140)',
|
||||||
|
'rgb(140, 180, 255)',
|
||||||
|
'rgb(160, 255, 160)',
|
||||||
|
'rgb(255, 140, 120)',
|
||||||
|
'rgb(160, 140, 200)',
|
||||||
|
'rgb(255, 220, 140)',
|
||||||
|
'rgb(140, 255, 255)',
|
||||||
|
'rgb(255, 160, 140)',
|
||||||
|
'rgb(160, 255, 160)',
|
||||||
|
'rgb(160, 160, 255)'
|
||||||
|
],
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: 'bottom',
|
||||||
|
align: 'start',
|
||||||
|
fullWidth: false,
|
||||||
|
labels: {
|
||||||
|
font: {
|
||||||
|
weight: 'bold'
|
||||||
|
},
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
chart.data.labels = chartLabels;
|
||||||
|
chart.data.datasets[0].data = chartValues;
|
||||||
|
chart.update();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if ($monthIncome) {
|
||||||
|
createGraph();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
createGraph();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="chart" style="background-color: {$globalStyles.mainColor}">
|
||||||
|
<canvas bind:this={chartCanvas}></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#chart {
|
||||||
|
min-width: 0;
|
||||||
|
min-height:0;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||||
|
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin: 0 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chart:hover {
|
||||||
|
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 900px) {
|
||||||
|
#chart {
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
<script>
|
||||||
|
import {incomeTypes} from "../../../stores.js";
|
||||||
|
import { slide } from 'svelte/transition'
|
||||||
|
export let item;
|
||||||
|
export let isOn;
|
||||||
|
|
||||||
|
function handleSave() {
|
||||||
|
const amount = document.getElementById('amountInput').value;
|
||||||
|
const expenseCategory = document.getElementById('incomeCategory').value;
|
||||||
|
|
||||||
|
console.log("tryna save: " + item.incomeId + " " + amount + " " + expenseCategory)
|
||||||
|
// saveFunction(item.expenseId, amount, expenseCategory);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div style="display: flex; flex-direction: column" transition:slide>
|
||||||
|
<span id="textf" style="margin-top: 10px; text-align: center">Edit Entry</span>
|
||||||
|
<input type="text" id="amountInput" bind:value={item.amount}>
|
||||||
|
<select id="incomeCategory" class="form-control">
|
||||||
|
{#each $incomeTypes as income (income.id)}
|
||||||
|
{#if income.id !== undefined}
|
||||||
|
{#if income.id === item.incomeCategory.id}
|
||||||
|
<option value={income.id} selected>{income.name}</option>
|
||||||
|
{:else}
|
||||||
|
<option value={income.id}>{income.name}</option>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
<div style="margin: 10px; display:flex; flex-direction: row; justify-content: space-evenly">
|
||||||
|
<button class="buttonCL" id="saveBtn" on:click={handleSave}>SAVE</button>
|
||||||
|
<button class="buttonCL" id="cancelBtn" on:click={() => isOn = false}>CANCEL</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
#textf {
|
||||||
|
font-family: "Inter UI","SF Pro Display",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
padding: 12px 20px;
|
||||||
|
margin: 8px 0;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 12px 20px;
|
||||||
|
margin: 8px 0;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#saveBtn {
|
||||||
|
background-image: linear-gradient(92.88deg, #455EB5 9.16%, #5643CC 43.89%, #673FD7 64.72%);
|
||||||
|
border-radius: 8px;
|
||||||
|
border-style: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #FFFFFF;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-family: "Inter UI","SF Pro Display",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
height: 3rem;
|
||||||
|
padding: 0 1.6rem;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: rgba(0, 0, 0, 0.25) 0 3px 8px;
|
||||||
|
transition: all .5s;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
touch-action: manipulation;
|
||||||
|
}
|
||||||
|
|
||||||
|
#saveBtn:hover {
|
||||||
|
box-shadow: rgba(80, 63, 205, 0.5) 0 1px 30px;
|
||||||
|
transition-duration: .1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cancelBtn {
|
||||||
|
background-image: linear-gradient(92.88deg, #455EB5 9.16%, #5643CC 43.89%, #673FD7 64.72%);
|
||||||
|
border-radius: 8px;
|
||||||
|
border-style: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #FFFFFF;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-family: "Inter UI","SF Pro Display",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
height: 3rem;
|
||||||
|
padding: 0 1.6rem;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: rgba(0, 0, 0, 0.25) 0 3px 8px;
|
||||||
|
transition: all .5s;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
touch-action: manipulation;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cancelBtn:hover {
|
||||||
|
box-shadow: rgba(80, 63, 205, 0.5) 0 1px 30px;
|
||||||
|
transition-duration: .1s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user