diff --git a/html/javascript/monthlyscript.js b/html/javascript/monthlyscript.js
index a5b00f3..d9ac574 100644
--- a/html/javascript/monthlyscript.js
+++ b/html/javascript/monthlyscript.js
@@ -106,161 +106,203 @@ function postDataCard() {
}
//------------------------------------------------- KALAU MAU TAMBAH CHART DISINI!!!!! ------------------------------------------------
-
-// ------------------------------------- BARCHART STATE HIGHEST SALES -------------------------------------
-// Fungsi untuk memproses data penjualan dan mendapatkan negara bagian dengan penjualan tertinggi
-function processSalesData(data) {
- const aggregatedData = {};
-
- data.forEach(row => {
- const state = row.State;
- const sales = parseFloat(row.Sales.replace(/\$/g, '').replace(/,/g, ''));
- if (aggregatedData[state]) {
- aggregatedData[state] += sales;
- } else {
- aggregatedData[state] = sales;
- }
- });
+//------------------------------------------------- CHART TOTAL SALES DAN PROFIT ROW 1 LEFT------------------------------------------------
+// Proses dan buat diagram
+fetchData(DataUrl).then(data => {
+ // Asumsikan data adalah array dari pesanan
+ let totalPenjualan = 0;
+ let totalProfit = 0;
- // Mengubah objek aggregatedData menjadi array untuk diurutkan
- const sortedDataArray = Object.entries(aggregatedData).sort((a, b) => b[1] - a[1]);
+ data.forEach(pesanan => {
+ // Hapus '$' dan ',' dari string penjualan dan profit, lalu konversi ke float
+ let penjualan = parseFloat(pesanan.Sales.replace(/[$,]/g, ''));
+ let profit = parseFloat(pesanan.Profit.replace(/[$,]/g, ''));
- // Mengembalikan objek yang diurutkan
- const sortedData = {};
- sortedDataArray.forEach(([state, sales]) => {
- sortedData[state] = sales;
+ totalPenjualan += penjualan;
+ totalProfit += profit;
});
- return sortedData;
-}
-
-// Variabel global untuk chart
-let BarChartSales = null;
-
-// Fungsi untuk membuat bar chart
-function createBarChartSalesState(data) {
- const ctx = document.getElementById("BarChartSalesPerState").getContext("2d");
- if (BarChartSales != null) {
- BarChartSales.destroy(); // Hapus chart sebelumnya jika ada
- }
-
- BarChartSales = new Chart(ctx, {
- type: "bar",
+ // Buat diagram batang
+ const ctx = document.getElementById('totalChart').getContext('2d');
+ const totalChart = new Chart(ctx, {
+ type: 'bar',
data: {
- labels: Object.keys(data), // Label adalah nama negara bagian
- datasets: [
- {
- label: "Total Sales by State",
- data: Object.values(data), // Data adalah total penjualan
- backgroundColor: 'rgba(255, 143, 0, 1)',
- borderColor: 'rgba(255, 143, 0, 1)',
- borderWidth: 1,
- },
- ],
+ labels: ['Total Penjualan', 'Total Profit'],
+ datasets: [{
+ label: 'Penjualan',
+ data: [totalPenjualan, 0], // Penjualan pada label pertama
+ backgroundColor: 'orange',
+ borderColor: 'orange',
+ borderWidth: 1
+ }, {
+ label: 'Profit',
+ data: [0, totalProfit], // Profit pada label kedua
+ backgroundColor: 'black',
+ borderColor: 'black',
+ borderWidth: 1
+ }]
},
options: {
- responsive: true,
- maintainAspectRatio: false,
scales: {
- y: {
- beginAtZero: true,
- ticks: {
- callback: function(value) {
- return '$' + value.toLocaleString(); // Format angka menjadi dolar
- }
- }
+ x: {
+ stacked: true,
},
+ y: {
+ beginAtZero: true
+ }
},
- },
+ plugins: {
+ legend: {
+ display: true,
+ labels: {
+ color: 'black'
+ }
+ }
+ }
+ }
});
-}
+});
-// Ambil data sales dari server, proses, dan buat chart
-fetchData(DataUrl)
- .then(data => {
- const processedData = processSalesData(data);
- createBarChartSalesState(processedData);
- });
+// ------------------------------------- BARCHART 10 STATE HIGHEST SALES ROW 1 RIGHT -------------------------------------
+// Fungsi untuk memproses data penjualan dan mendapatkan negara bagian dengan penjualan tertinggi
+// Fetch data from the URL
+fetchData(DataUrl).then(data => {
+ if (!data) return;
-// ------------------------------------- BARCHART STATE HIGHEST PROFIT -------------------------------------
-// Fungsi untuk memproses data profit dan mendapatkan profit per negara bagian
-function processProfitData(data) {
- const aggregatedData = {};
+ // Process data to aggregate sales by state
+ const stateSales = {};
- data.forEach(row => {
- const state = row.State;
- const profit = parseFloat(row.Profit.replace(/\$/g, '').replace(/,/g, ''));
+ data.forEach(order => {
+ const state = order.State;
+ const sales = parseFloat(order.Sales.replace(/[^0-9.-]+/g, ""));
- if (aggregatedData[state]) {
- aggregatedData[state] += profit;
- } else {
- aggregatedData[state] = profit;
+ if (!stateSales[state]) {
+ stateSales[state] = 0;
}
- });
- // Mengubah objek aggregatedData menjadi array untuk diurutkan
- const sortedDataArray = Object.entries(aggregatedData).sort((a, b) => b[1] - a[1]);
-
- // Mengembalikan objek yang diurutkan
- const sortedData = {};
- sortedDataArray.forEach(([state, profit]) => {
- sortedData[state] = profit;
+ stateSales[state] += sales;
});
- return sortedData;
-}
+ // Convert the stateSales object into an array of [state, sales] pairs
+ const salesArray = Object.entries(stateSales);
-// Variabel global untuk chart
-let BarChartProfit = null;
+ // Sort the array by sales in descending order and take the top 10 states
+ const top10Sales = salesArray.sort((a, b) => b[1] - a[1]).slice(0, 10);
-// Fungsi untuk membuat bar chart
-function createBarChartProfitState(data) {
- const ctx = document.getElementById("BarChartProfitPerState").getContext("2d");
- if (BarChartProfit != null) {
- BarChartProfit.destroy(); // Hapus chart sebelumnya jika ada
- }
+ // Separate the top 10 states and their sales into separate arrays
+ const states = top10Sales.map(item => item[0]);
+ const sales = top10Sales.map(item => item[1]);
- BarChartProfit = new Chart(ctx, {
- type: "bar",
+ // Create the bar chart using Chart.js
+ const ctx = document.getElementById('salesChart').getContext('2d');
+ new Chart(ctx, {
+ type: 'bar',
data: {
- labels: Object.keys(data), // Label adalah nama negara bagian
- datasets: [
- {
- label: "Total Profit by State",
- data: Object.values(data), // Data adalah total profit
- backgroundColor: 'rgba(0, 0, 0, 1)',
- borderColor: 'rgba(0, 0, 0, 1)',
- borderWidth: 1,
- },
- ],
+ labels: states,
+ datasets: [{
+ label: 'Sales by State',
+ data: sales,
+ backgroundColor: 'orange',
+ borderColor: 'orange',
+ borderWidth: 1
+ }]
},
options: {
- responsive: true,
- maintainAspectRatio: false,
scales: {
y: {
- beginAtZero: true,
- ticks: {
- callback: function(value) {
- return '$' + value.toLocaleString(); // Format angka menjadi dolar
- }
- }
- },
- },
- },
+ beginAtZero: true
+ }
+ }
+ }
+ });
+});
+
+//-------------------------------- TABEL SHIPMODE ----------------------------------
+let totalProfitTable = {}; // Define totalProfitTable globally
+let sortedShipModes = [];
+let sortDirection = 'desc'; // Initialize sort direction
+
+// Fungsi untuk memproses data profit berdasarkan kategori dan ship mode
+function calculateTotalProfitTable(orders) {
+ const totalProfit = {};
+
+ orders.forEach(order => {
+ const category = order["Category"];
+ const shipMode = order["Ship Mode"];
+ const profit = parseFloat(order.Profit.replace(/[^0-9.-]+/g, ''));
+
+ if (!totalProfit[shipMode]) {
+ totalProfit[shipMode] = { "Office Supplies": 0, "Technology": 0, "Furniture": 0 };
+ }
+
+ if (category === "Technology" || category === "Office Supplies" || category === "Furniture") {
+ totalProfit[shipMode][category] += profit;
+ }
});
+
+ return totalProfit;
}
+// Fungsi untuk menampilkan data pada tabel
+function displayProfitTable(totalProfitTable) {
+ const tableBody = document.getElementById('profitpercategory-body');
+
+ // Kosongkan isi tabel sebelum menambahkan data baru
+ tableBody.innerHTML = '';
+
+ // Tambahkan baris untuk setiap ship mode
+ sortedShipModes.forEach(shipMode => {
+ const row = `
+ ${shipMode} |
+ ${totalProfitTable[shipMode]["Office Supplies"].toLocaleString('en-US', { style: 'currency', currency: 'USD' })} |
+ ${totalProfitTable[shipMode]["Technology"].toLocaleString('en-US', { style: 'currency', currency: 'USD' })} |
+ ${totalProfitTable[shipMode]["Furniture"].toLocaleString('en-US', { style: 'currency', currency: 'USD' })} |
+
`;
+ tableBody.innerHTML += row;
+ });
+}
-// Ambil data profit dari server, proses, dan buat chart
-fetchData(DataUrl)
- .then(data => {
- const processedData = processProfitData(data);
- createBarChartProfitState(processedData);
- })
+// Fungsi untuk mengurutkan data berdasarkan total profit
+function sortShipModes(totalProfitTable, direction) {
+ const shipModes = Object.keys(totalProfitTable);
+
+ shipModes.sort((a, b) => {
+ const totalProfitA = totalProfitTable[a]["Technology"] + totalProfitTable[a]["Office Supplies"] + totalProfitTable[a]["Furniture"];
+ const totalProfitB = totalProfitTable[b]["Technology"] + totalProfitTable[b]["Office Supplies"] + totalProfitTable[b]["Furniture"];
+ return direction === 'asc' ? totalProfitA - totalProfitB : totalProfitB - totalProfitA;
+ });
+
+ return shipModes;
+}
+
+// Fungsi untuk mengambil data dan memperbarui tabel
+function fetchDataAndRenderTable() {
+ fetch(DataUrl)
+ .then(response => response.json())
+ .then(data => {
+ totalProfitTable = calculateTotalProfitTable(data);
+ sortedShipModes = sortShipModes(totalProfitTable, sortDirection);
+ displayProfitTable(totalProfitTable);
+ })
+ .catch(error => console.error('Error fetching data:', error));
+}
-//-------------------------------- LINE CHART MONTHLY SALES PERFORMANCE ----------------------------------
+// Inisialisasi data dan render tabel saat halaman dimuat
+document.addEventListener('DOMContentLoaded', () => {
+ fetchDataAndRenderTable();
+});
+
+// Fungsi Filter Tabel
+function filterTable() {
+ fetchData(DataUrl).then(data => {
+ const filteredData = applyFilters(data);
+ // Use the global total Profit Table variable
+ totalProfitTable = calculateTotalProfitTable(filteredData);
+ displayProfitTable(totalProfitTable);
+ });
+}
+//-------------------------------- LINE CHART MONTHLY SALES PERFORMANCE ROW 2 ----------------------------------
// Fungsi untuk memproses data penjualan bulanan
const preprocessData = (data) => {
const result = {};
@@ -344,8 +386,279 @@ fetch(DataUrl)
})
.catch(error => console.error('Error fetching data:', error));
+ //------------------------------------------------ Most Profitable Category ROW 3 LEFT ------------------------------------------------
+// Proses dan buat diagram
+fetchData(DataUrl).then(data => {
+ // Objek untuk menyimpan total penjualan dan profit per kategori
+ const categories = {};
+
+ data.forEach(pesanan => {
+ const category = pesanan.Category;
+
+ // Hapus '$' dan ',' dari string penjualan dan profit, lalu konversi ke float
+ const penjualan = parseFloat(pesanan.Sales.replace(/[$,]/g, ''));
+ const profit = parseFloat(pesanan.Profit.replace(/[$,]/g, ''));
+
+ // Jika kategori belum ada, inisialisasi dengan nilai awal
+ if (!categories[category]) {
+ categories[category] = { totalPenjualan: 0, totalProfit: 0 };
+ }
+
+ // Tambahkan penjualan dan profit ke kategori
+ categories[category].totalPenjualan += penjualan;
+ categories[category].totalProfit += profit;
+ });
+
+ // Ekstraksi kategori, total penjualan dan total profit ke dalam array terpisah
+ const categoryLabels = Object.keys(categories);
+ const totalPenjualanData = categoryLabels.map(category => categories[category].totalPenjualan);
+ const totalProfitData = categoryLabels.map(category => categories[category].totalProfit);
+
+ // Buat diagram batang horizontal
+ const ctx = document.getElementById('totalCategory').getContext('2d');
+ const totalCategory = new Chart(ctx, {
+ type: 'bar',
+ data: {
+ labels: categoryLabels,
+ datasets: [
+ {
+ label: 'Total Penjualan',
+ data: totalPenjualanData,
+ backgroundColor: 'orange',
+ borderColor: 'range',
+ borderWidth: 1
+ },
+ {
+ label: 'Total Profit',
+ data: totalProfitData,
+ backgroundColor: 'black',
+ borderColor: 'black',
+ borderWidth: 1
+ }
+ ]
+ },
+ options: {
+ indexAxis: 'y',
+ scales: {
+ x: {
+ beginAtZero: true
+ }
+ }
+ }
+ });
+});
+
+
+
+
+//------------------------------------------------ The most Profitable and Highest Sales ROW 3 RIGHT------------------------------------------------
+// Ambil data dari JSON
+function fetchData(url) {
+ return fetch(url)
+ .then(response => {
+ if (!response.ok) {
+ throw new Error('Network response was not ok');
+ }
+ return response.json();
+ })
+ .catch(error => {
+ console.error('There was a problem with the fetch operation:', error);
+ });
+}
+
+// Fungsi untuk mengubah format data
+function processData(data) {
+ const products = {};
+
+ // Loop melalui setiap item dalam data
+ data.forEach(item => {
+ const productName = item["Product Name"];
+ const profit = parseFloat(item["Profit"].replace("$", "").replace(",", ""));
+ const sales = parseFloat(item["Sales"].replace("$", "").replace(",", ""));
+
+ // Jika nama produk sudah ada dalam objek products, tambahkan profit dan sales
+ if (products[productName]) {
+ products[productName].profit += profit;
+ products[productName].sales += sales;
+ } else { // Jika tidak, buat entri baru untuk produk tersebut
+ products[productName] = {
+ profit: profit,
+ sales: sales
+ };
+ }
+ });
+
+ // Mengurutkan produk berdasarkan profit tertinggi
+ const sortedProducts = Object.entries(products).sort((a, b) => b[1].profit - a[1].profit).slice(0, 10);
+
+ return sortedProducts;
+}
+
+// Membuat chart
+async function createChart() {
+ const data = await fetchData(DataUrl);
+ const processedData = processData(data);
+
+ const productNames = processedData.map(item => item[0]);
+ const profits = processedData.map(item => item[1].profit);
+ const sales = processedData.map(item => item[1].sales);
+
+ const ctx = document.getElementById('myChart').getContext('2d');
+ const myChart = new Chart(ctx, {
+ type: 'bar',
+ data: {
+ labels: productNames,
+ datasets: [{
+ label: 'Profit',
+ data: profits,
+ backgroundColor: 'orange',
+ borderColor: 'black',
+ borderWidth: 1
+ }, {
+ label: 'Sales',
+ data: sales,
+ backgroundColor: 'black',
+ borderColor: 'black',
+ borderWidth: 1
+ }]
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ ticks: {
+ display: false // Menyembunyikan label di sumbu x
+ }
+ }],
+ yAxes: [{
+ ticks: {
+ beginAtZero: true
+ }
+ }]
+ }
+ }
+ });
+}
+
+// Panggil fungsi untuk membuat chart
+createChart();
+
+//------------------------------------------------ BARCHART SUB CATEGORY TERTINGGI SALES ROW 4 LEFT ------------------------------------------------
+// Fetch data from the URL
+ // Fetch data from the URL
+ fetchData(DataUrl).then(data => {
+ if (!data) return;
+
+ // Process data to aggregate sales by sub-category
+ const subCategorySales = {};
+
+ data.forEach(order => {
+ const subCategory = order["Sub-Category"];
+ const sales = parseFloat(order.Sales.replace(/[^0-9.-]+/g, ""));
+
+ if (!subCategorySales[subCategory]) {
+ subCategorySales[subCategory] = 0;
+ }
+
+ subCategorySales[subCategory] += sales;
+ });
+
+ // Convert the subCategorySales object into an array of [subCategory, sales] pairs
+ const salesArray = Object.entries(subCategorySales);
+
+ // Sort the array by sales in descending order and take the top 10 sub-categories
+ const top10Sales = salesArray.sort((a, b) => b[1] - a[1]).slice(0, 10);
+
+ // Separate the top 10 sub-categories and their sales into separate arrays
+ const subCategories = top10Sales.map(item => item[0]);
+ const sales = top10Sales.map(item => item[1]);
+
+ // Create the horizontal bar chart using Chart.js
+ const ctx = document.getElementById('SubsalesChart').getContext('2d');
+ new Chart(ctx, {
+ type: 'bar',
+ data: {
+ labels: subCategories,
+ datasets: [{
+ label: 'Sales by Sub-Category',
+ data: sales,
+ backgroundColor: 'orange',
+ borderColor: 'orange',
+ borderWidth: 1
+ }]
+ },
+ options: {
+ indexAxis: 'y',
+ scales: {
+ x: {
+ beginAtZero: true
+ }
+ }
+ }
+ });
+});
+
+fetch(DataUrl)
+ .then(response => response.json())
+ .then(data => {
+ const processedDataLineChart = preprocessData(data);
+ createLineChart(processedDataLineChart);
+ })
+ .catch(error => console.error('Error fetching data:', error));
+
+
+// ------------------------------------- BARCHART STATE HIGHEST PROFIT ROW 4 RIGHT-------------------------------------
+// Fungsi untuk memproses data profit dan mendapatkan profit per negara bagian
+// Fetch data from the URL
+fetchData(DataUrl).then(data => {
+ if (!data) return;
+
+ // Process data to aggregate profit by state
+ const stateProfit = {};
+
+ data.forEach(order => {
+ const state = order.State;
+ const profit = parseFloat(order.Profit.replace(/[^0-9.-]+/g, ""));
+
+ if (!stateProfit[state]) {
+ stateProfit[state] = 0;
+ }
+
+ stateProfit[state] += profit;
+ });
+
+ // Convert the stateProfit object into an array of [state, profit] pairs
+ const profitArray = Object.entries(stateProfit);
+
+ // Sort the array by profit in descending order and take the top 10 states
+ const top10Profit = profitArray.sort((a, b) => b[1] - a[1]).slice(0, 10);
+ // Separate the top 10 states and their profit into separate arrays
+ const states = top10Profit.map(item => item[0]);
+ const profits = top10Profit.map(item => item[1]);
+ // Create the bar chart using Chart.js
+ const ctx = document.getElementById('profitChart').getContext('2d');
+ new Chart(ctx, {
+ type: 'bar',
+ data: {
+ labels: states,
+ datasets: [{
+ label: 'Profit by State',
+ data: profits,
+ backgroundColor: 'black',
+ borderColor: 'black',
+ borderWidth: 1
+ }]
+ },
+ options: {
+ scales: {
+ y: {
+ beginAtZero: true
+ }
+ }
+ }
+ });
+});
diff --git a/html/monthly.html b/html/monthly.html
index 9630876..6b0db42 100644
--- a/html/monthly.html
+++ b/html/monthly.html
@@ -110,23 +110,16 @@
-
Sales by Category
-
+
Total Sales and Profit
+
-
-
State with the Highest Profit
-
+
State with the Higest Sales
+
-
-
Monthly Sales Performance
-
-
-
-
Profit Per Category
@@ -144,17 +137,37 @@ Profit Per Category
-
+
+
+
Monthly Sales Performance
+
+
+
+
+
+
+
+
+
The most Profitable and Highest Sales
+
+
+
+
The most Profitable and Highest Sales
+
+
+
+
+
-
Most Profitable Category
-
+
Top 10 Sub Category Sales
+
-
-
Top 5 Sub Category Sales
-
+
State with the Highest Profit
+
+
diff --git a/testfitur.html b/testfitur.html
index 0353fd4..0acff55 100644
--- a/testfitur.html
+++ b/testfitur.html
@@ -1,84 +1,109 @@
-
-
- Choropleth Map Chart
-
-
+
+
+ Grafik Garis Penjualan Bulanan
+
-
+
+
+
+
-
-