diff --git a/src/lib/components/AnalystEstimate.svelte b/src/lib/components/AnalystEstimate.svelte
index 1dc82f6c..67ef71c3 100644
--- a/src/lib/components/AnalystEstimate.svelte
+++ b/src/lib/components/AnalystEstimate.svelte
@@ -34,36 +34,61 @@
let lowEPSList = [];
let highEPSList = [];
- let revenueGrowthList = [];
- let epsGrowthList = [];
+ let revenueAvgGrowthList = [];
+ let revenueLowGrowthList = [];
+ let epsAvgGrowthList = [];
let displayData = "Revenue";
- function computeGrowthSingleList(data, actualList) {
- let lastNonNull = actualList
- ?.filter((value) => value !== null)
- .slice(-1)[0];
- const newList = data;
- newList?.unshift(lastNonNull);
- // Remove leading null values
- while (newList?.length > 0 && newList[0] === null) {
- newList?.shift();
- }
+ function fillMissingDates(dates, highGrowthList) {
+ // Create a map from the highGrowthList for quick lookup
+ const highGrowthMap = new Map(
+ highGrowthList?.map((item) => [`FY${item.FY}`, item]),
+ );
- let growthPercentages = [];
+ // Generate the complete list based on the dates array
+ return dates.map(
+ (date) =>
+ highGrowthMap.get(date) || {
+ FY: date?.slice(2),
+ val: null,
+ growth: null,
+ },
+ );
+ }
+
+ function computeGrowthSingleList(data, actualList) {
+ // Find the last non-null entry in actualList
+ let lastNonNull = actualList
+ ?.filter((entry) => entry?.val !== null)
+ ?.slice(-1)[0];
+
+ // Add the last non-null entry from actualList to the beginning of data
+ const newList = [lastNonNull, ...data];
+
+ // Calculate growth and include it in the objects
+ let resultList = [];
for (let i = 1; i < newList?.length; i++) {
let previous = newList[i - 1];
let current = newList[i];
- // Check if previous or current is null to avoid NaN results
- if (previous !== null && current !== null) {
- let growth = (((current - previous) / previous) * 100)?.toFixed(2);
- growthPercentages.push(Number(growth)); // Convert to number
+ // Calculate growth only if both values are non-null
+ let growth = null;
+ if (previous.val !== null && current.val !== null) {
+ growth = (((current.val - previous.val) / previous.val) * 100)?.toFixed(
+ 2,
+ );
}
- }
- return growthPercentages;
+ // Add FY, val, and growth to the result list
+ resultList.push({
+ FY: current.FY,
+ val: current.val,
+ growth: growth !== null ? Number(growth) : null, // Convert growth to number or leave as null
+ });
+ }
+ return resultList;
}
function computeGrowthList(tableActualRevenue, tableForecastRevenue) {
@@ -188,26 +213,48 @@
// Assign to global variables based on dataType
if (dataType === "Revenue") {
revenueDateList = dates?.slice(currentYearIndex) || [];
- avgRevenueList = avgList?.slice(currentYearIndex) || [];
- lowRevenueList = lowList?.slice(currentYearIndex) || [];
- highRevenueList = highList?.slice(currentYearIndex) || [];
+ avgRevenueList =
+ avgList?.slice(currentYearIndex)?.map((val, index) => ({
+ FY: revenueDateList[index]?.slice(2),
+ val: val,
+ })) || [];
+ lowRevenueList =
+ lowList?.slice(currentYearIndex)?.map((val, index) => ({
+ FY: revenueDateList[index]?.slice(2),
+ val: val,
+ })) || [];
+ highRevenueList =
+ highList?.slice(currentYearIndex)?.map((val, index) => ({
+ FY: revenueDateList[index]?.slice(2),
+ val: val,
+ })) || [];
} else if (dataType === "EPS") {
epsDateList = dates?.slice(currentYearIndex) || [];
- avgEPSList = avgList?.slice(currentYearIndex) || [];
- lowEPSList = lowList?.slice(currentYearIndex) || [];
- highEPSList = highList?.slice(currentYearIndex) || [];
+ avgEPSList =
+ avgList?.slice(currentYearIndex)?.map((val, index) => ({
+ FY: epsDateList[index]?.slice(2),
+ val: val,
+ })) || [];
+ lowEPSList =
+ lowList?.slice(currentYearIndex)?.map((val, index) => ({
+ FY: epsDateList[index]?.slice(2),
+ val: val,
+ })) || [];
+ highEPSList =
+ highList?.slice(currentYearIndex)?.map((val, index) => ({
+ FY: epsDateList[index]?.slice(2),
+ val: val,
+ })) || [];
}
- const growthList = dates.map((date) => {
+ const growthList = dates?.map((date) => {
const fy = parseInt(date.replace("FY", ""), 10); // Extract numeric FY value
const listToUse =
- dataType === "Revenue" ? revenueGrowthList : epsGrowthList; // Select the correct growth list
+ dataType === "Revenue" ? revenueAvgGrowthList : epsAvgGrowthList; // Select the correct growth list
const growth = listToUse.find((r) => r.FY === fy); // Find matching FY
- return growth ? growth.growth : null; // Return growth or null if not found
+ return growth ? growth?.growth : null; // Return growth or null if not found
});
- console.log(growthList);
-
const option = {
silent: true,
tooltip: {
@@ -294,6 +341,32 @@
],
};
+ let highGrowthList = [];
+ let lowGrowthList = [];
+ if (dataType === "Revenue") {
+ highGrowthList = computeGrowthSingleList(
+ highRevenueList,
+ tableActualRevenue,
+ );
+ lowGrowthList = computeGrowthSingleList(
+ lowRevenueList,
+ tableActualRevenue,
+ );
+ } else {
+ highGrowthList = computeGrowthSingleList(highEPSList, tableActualEPS);
+ lowGrowthList = computeGrowthSingleList(lowEPSList, tableActualEPS);
+ }
+
+ console.log(highGrowthList);
+ highGrowthList = fillMissingDates(dates, highGrowthList)?.map(
+ (item) => item?.growth,
+ );
+ console.log(highGrowthList);
+
+ lowGrowthList = fillMissingDates(dates, lowGrowthList)?.map(
+ (item) => item?.growth,
+ );
+
const optionsGrowth = {
animation: false,
grid: {
@@ -341,8 +414,18 @@
renderItem: (params, api) => {
const xValue = api.value(0);
const yValue = api.value(1);
- const high = yValue + yValue / 2; // High value (half above the value)
- const low = yValue - yValue / 2; // Low value (half below the value)
+
+ // Select high and low lists based on dataType
+ const highList = highGrowthList;
+ const lowList = lowGrowthList;
+
+ // Retrieve the corresponding high and low values
+ const high = highList[params.dataIndex];
+ const low = lowList[params.dataIndex];
+
+ // Skip rendering error bars if high or low values are null or undefined
+ if (high == null || low == null) return; // Null or undefined values are skipped
+
const x = api.coord([xValue, yValue])[0];
const highCoord = api.coord([xValue, high])[1];
const lowCoord = api.coord([xValue, low])[1];
@@ -360,7 +443,7 @@
},
style: {
stroke: "#fff",
- lineWidth: 1.5, // Set thicker line width
+ lineWidth: 2, // Set thicker line width
},
},
{
@@ -373,7 +456,7 @@
},
style: {
stroke: "#fff",
- lineWidth: 1.5, // Set thicker line width
+ lineWidth: 2, // Set thicker line width
},
},
{
@@ -386,7 +469,7 @@
},
style: {
stroke: "#fff",
- lineWidth: 1.5, // Set thicker line width
+ lineWidth: 2, // Set thicker line width
},
},
],
@@ -405,14 +488,20 @@
formatter: (params) => {
const dataIndex = params[0].dataIndex;
const mainValue = params[0].value;
- const high = mainValue + mainValue / 2;
- const low = mainValue - mainValue / 2;
+
+ // Select high and low lists based on dataType
+ const highList = highGrowthList;
+ const lowList = lowGrowthList;
+
+ // Retrieve the corresponding high and low values
+ const high = highList[dataIndex];
+ const low = lowList[dataIndex];
return `
${dates[dataIndex]}
- High: ${high?.toFixed(2) + "%"}
- Avg: ${mainValue?.toFixed(2) + "%"}
- Low: ${low?.toFixed(2) + "%"}
+ High: ${high ? high?.toFixed(2) : "N/A"}
+ Avg: ${mainValue?.toFixed(2)}
+ Low: ${low ? low?.toFixed(2) : "N/A"}
`;
},
},
@@ -435,8 +524,8 @@
tableActualEPS = [];
tableForecastEPS = [];
- revenueGrowthList = [];
- epsGrowthList = [];
+ revenueAvgGrowthList = [];
+ epsAvgGrowthList = [];
let filteredData =
analystEstimateList?.filter((item) => item.date >= 2015) ?? [];
@@ -467,12 +556,12 @@
});
});
//Values coincide with table values for crosscheck
- revenueGrowthList = computeGrowthList(
+ revenueAvgGrowthList = computeGrowthList(
tableActualRevenue,
tableForecastRevenue,
);
- epsGrowthList = computeGrowthList(tableActualEPS, tableForecastEPS);
+ epsAvgGrowthList = computeGrowthList(tableActualEPS, tableForecastEPS);
}
$: {
@@ -724,7 +813,7 @@
>