add download button to employee page
This commit is contained in:
parent
4cef1d8a35
commit
b80737d210
@ -332,9 +332,9 @@ function findIndex(data) {
|
|||||||
<table class="table table-sm shaodow table-pin-cols table-compact rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B]">
|
<table class="table table-sm shaodow table-pin-cols table-compact rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B]">
|
||||||
<thead class="">
|
<thead class="">
|
||||||
<tr class="">
|
<tr class="">
|
||||||
<th class="bg-[#27272A] border-b border-[#000] text-white font-semibold text-sm sm:text-[1rem] text-start">Year</th>
|
<th class="bg-[#27272A] border-b border-[#000] text-white font-semibold text-sm text-start">Year</th>
|
||||||
{#each xData as item}
|
{#each xData as item}
|
||||||
<td class="z-20 bg-[#27272A] border-b border-[#000] text-white font-semibold text-sm sm:text-[1rem] text-center bg-[#09090B]">{"FY" + item}</td>
|
<td class="z-20 bg-[#27272A] border-b border-[#000] text-white font-semibold text-sm text-end bg-[#09090B]">{"FY" + item}</td>
|
||||||
{/each}
|
{/each}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
@ -1,33 +1,35 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import {
|
||||||
import {numberOfUnreadNotification, displayCompanyName, stockTicker} from '$lib/store';
|
numberOfUnreadNotification,
|
||||||
|
displayCompanyName,
|
||||||
|
stockTicker,
|
||||||
|
} from "$lib/store";
|
||||||
import * as DropdownMenu from "$lib/components/shadcn/dropdown-menu/index.js";
|
import * as DropdownMenu from "$lib/components/shadcn/dropdown-menu/index.js";
|
||||||
import { Button } from "$lib/components/shadcn/button/index.js";
|
import { Button } from "$lib/components/shadcn/button/index.js";
|
||||||
import { Chart } from 'svelte-echarts'
|
import { Chart } from "svelte-echarts";
|
||||||
import { init, use } from 'echarts/core'
|
import { init, use } from "echarts/core";
|
||||||
import { BarChart } from 'echarts/charts'
|
import { BarChart } from "echarts/charts";
|
||||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
import { GridComponent, TooltipComponent } from "echarts/components";
|
||||||
import { CanvasRenderer } from 'echarts/renderers'
|
import { CanvasRenderer } from "echarts/renderers";
|
||||||
use([BarChart, GridComponent, TooltipComponent, CanvasRenderer])
|
use([BarChart, GridComponent, TooltipComponent, CanvasRenderer]);
|
||||||
|
|
||||||
import { abbreviateNumber } from '$lib/utils';
|
import { abbreviateNumber } from "$lib/utils";
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
let employeeHistory = data?.getHistoryEmployee ?? [];
|
let employeeHistory = data?.getHistoryEmployee ?? [];
|
||||||
let historyList = sortByDate(employeeHistory);
|
let historyList = sortByDate(employeeHistory);
|
||||||
|
|
||||||
let employees = 'n/a';
|
let employees = "n/a";
|
||||||
let changeRate = 'n/a';
|
let changeRate = "n/a";
|
||||||
let growthRate = 'n/a';
|
let growthRate = "n/a";
|
||||||
|
|
||||||
let optionsTotal;
|
let optionsTotal;
|
||||||
let optionsChange;
|
let optionsChange;
|
||||||
let optionsGrowth;
|
let optionsGrowth;
|
||||||
let dateDistance = false;
|
let dateDistance = false;
|
||||||
|
|
||||||
let sortBy = 'Total';
|
let sortBy = "Total";
|
||||||
|
|
||||||
|
|
||||||
function sortByDate(liste) {
|
function sortByDate(liste) {
|
||||||
//Slice copies the list otherwise employeesHistory will reverse too
|
//Slice copies the list otherwise employeesHistory will reverse too
|
||||||
@ -36,19 +38,15 @@ function sortByDate(liste) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function selectSortingMethod(state: string) {
|
function selectSortingMethod(state: string) {
|
||||||
sortBy = state;
|
sortBy = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function plotTotal() {
|
function plotTotal() {
|
||||||
|
|
||||||
let dateList = [];
|
let dateList = [];
|
||||||
let employeeList = [];
|
let employeeList = [];
|
||||||
let growthList = [];
|
let growthList = [];
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < employeeHistory?.length; i++) {
|
for (let i = 0; i < employeeHistory?.length; i++) {
|
||||||
const current = employeeHistory[i]?.employeeCount;
|
const current = employeeHistory[i]?.employeeCount;
|
||||||
//const previousDividend = i === 0 ? 0 : employeeHistory[i - 1]?.dividend;
|
//const previousDividend = i === 0 ? 0 : employeeHistory[i - 1]?.dividend;
|
||||||
@ -59,62 +57,54 @@ function selectSortingMethod(state:string) {
|
|||||||
//const growthRate = ( (currentDividend - previousDividend) / previousDividend ) ;
|
//const growthRate = ( (currentDividend - previousDividend) / previousDividend ) ;
|
||||||
|
|
||||||
//growthList.push(growthRate?.toFixed(2))
|
//growthList.push(growthRate?.toFixed(2))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
animation: false,
|
animation: false,
|
||||||
grid: {
|
grid: {
|
||||||
left: '0%',
|
left: "0%",
|
||||||
right: '0%',
|
right: "0%",
|
||||||
top: '10%',
|
top: "10%",
|
||||||
bottom: '20%',
|
bottom: "20%",
|
||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
data: dateList,
|
data: dateList,
|
||||||
type: 'category',
|
type: "category",
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: '#fff',
|
color: "#fff",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: "value",
|
||||||
splitLine: {
|
splitLine: {
|
||||||
show: false, // Disable x-axis grid lines
|
show: false, // Disable x-axis grid lines
|
||||||
},
|
},
|
||||||
|
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
show: false // Hide y-axis labels
|
show: false, // Hide y-axis labels
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: [
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'Total Employees',
|
name: "Total Employees",
|
||||||
data: employeeList,
|
data: employeeList,
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
barWidth: '80%',
|
barWidth: "80%",
|
||||||
smooth: true,
|
smooth: true,
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: "axis",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function plotChange() {
|
function plotChange() {
|
||||||
|
|
||||||
let dateList = [];
|
let dateList = [];
|
||||||
let changeList = [];
|
let changeList = [];
|
||||||
|
|
||||||
@ -122,76 +112,66 @@ function selectSortingMethod(state:string) {
|
|||||||
const current = employeeHistory[i]?.employeeCount;
|
const current = employeeHistory[i]?.employeeCount;
|
||||||
const previous = i === 0 ? 0 : employeeHistory[i - 1]?.employeeCount;
|
const previous = i === 0 ? 0 : employeeHistory[i - 1]?.employeeCount;
|
||||||
|
|
||||||
const change = (current - previous) ;
|
const change = current - previous;
|
||||||
dateList?.push(employeeHistory[i]?.filingDate);
|
dateList?.push(employeeHistory[i]?.filingDate);
|
||||||
changeList?.push(change);
|
changeList?.push(change);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
animation: false,
|
animation: false,
|
||||||
grid: {
|
grid: {
|
||||||
left: '0%',
|
left: "0%",
|
||||||
right: '0%',
|
right: "0%",
|
||||||
top: '10%',
|
top: "10%",
|
||||||
bottom: '20%',
|
bottom: "20%",
|
||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
data: dateList,
|
data: dateList,
|
||||||
type: 'category',
|
type: "category",
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: '#fff'
|
color: "#fff",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: "value",
|
||||||
splitLine: {
|
splitLine: {
|
||||||
show: false, // Disable x-axis grid lines
|
show: false, // Disable x-axis grid lines
|
||||||
},
|
},
|
||||||
|
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
show: false // Hide y-axis labels
|
show: false, // Hide y-axis labels
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: [
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'Change of Numbers',
|
name: "Change of Numbers",
|
||||||
data: changeList,
|
data: changeList,
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
barWidth: '80%',
|
barWidth: "80%",
|
||||||
smooth: true,
|
smooth: true,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
// Define colors based on positive/negative values
|
// Define colors based on positive/negative values
|
||||||
color: function (params) {
|
color: function (params) {
|
||||||
return params.data >= 0 ? '#22C55E' : '#F71F4F';
|
return params.data >= 0 ? "#22C55E" : "#F71F4F";
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: "axis",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function plotGrowth() {
|
function plotGrowth() {
|
||||||
|
|
||||||
let dateList = [];
|
let dateList = [];
|
||||||
let growthList = [];
|
let growthList = [];
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < employeeHistory?.length; i++) {
|
for (let i = 0; i < employeeHistory?.length; i++) {
|
||||||
const current = employeeHistory[i]?.employeeCount;
|
const current = employeeHistory[i]?.employeeCount;
|
||||||
const previous = i === 0 ? 0 : employeeHistory[i - 1]?.employeeCount;
|
const previous = i === 0 ? 0 : employeeHistory[i - 1]?.employeeCount;
|
||||||
@ -209,114 +189,191 @@ function plotGrowth() {
|
|||||||
const options = {
|
const options = {
|
||||||
animation: false,
|
animation: false,
|
||||||
grid: {
|
grid: {
|
||||||
left: '0%',
|
left: "0%",
|
||||||
right: '0%',
|
right: "0%",
|
||||||
top: '10%',
|
top: "10%",
|
||||||
bottom: '20%',
|
bottom: "20%",
|
||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
data: dateList,
|
data: dateList,
|
||||||
type: 'category',
|
type: "category",
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: '#fff'
|
color: "#fff",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: "value",
|
||||||
splitLine: {
|
splitLine: {
|
||||||
show: false, // Disable x-axis grid lines
|
show: false, // Disable x-axis grid lines
|
||||||
},
|
},
|
||||||
|
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
show: false // Hide y-axis labels
|
show: false, // Hide y-axis labels
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: 'Growth [%]',
|
name: "Growth [%]",
|
||||||
data: growthList,
|
data: growthList,
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
barWidth: '80%',
|
barWidth: "80%",
|
||||||
smooth: true,
|
smooth: true,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
// Define colors based on positive/negative values
|
// Define colors based on positive/negative values
|
||||||
color: function (params) {
|
color: function (params) {
|
||||||
return params.data >= 0 ? '#22C55E' : '#F71F4F';
|
return params.data >= 0 ? "#22C55E" : "#F71F4F";
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: "axis",
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (employeeHistory?.length !== 0) {
|
||||||
|
|
||||||
if(employeeHistory?.length !== 0)
|
|
||||||
{
|
|
||||||
employees = employeeHistory?.at(-1)?.employeeCount;
|
employees = employeeHistory?.at(-1)?.employeeCount;
|
||||||
|
|
||||||
changeRate = employees - employeeHistory?.at(-2)?.employeeCount;
|
changeRate = employees - employeeHistory?.at(-2)?.employeeCount;
|
||||||
|
|
||||||
dateDistance = new Date(employeeHistory[employeeHistory?.length -1]['filingDate']) < new Date(new Date().setFullYear(new Date().getFullYear() - 1)) ? true : false;
|
dateDistance =
|
||||||
|
new Date(employeeHistory[employeeHistory?.length - 1]["filingDate"]) <
|
||||||
|
new Date(new Date().setFullYear(new Date().getFullYear() - 1))
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
|
||||||
|
growthRate = (
|
||||||
growthRate = ((employeeHistory[employeeHistory?.length -1]?.employeeCount/ employeeHistory[employeeHistory?.length -2]?.employeeCount -1 ) *100 )?.toFixed(2);
|
(employeeHistory[employeeHistory?.length - 1]?.employeeCount /
|
||||||
|
employeeHistory[employeeHistory?.length - 2]?.employeeCount -
|
||||||
|
1) *
|
||||||
|
100
|
||||||
|
)?.toFixed(2);
|
||||||
optionsTotal = plotTotal();
|
optionsTotal = plotTotal();
|
||||||
optionsChange = plotChange();
|
optionsChange = plotChange();
|
||||||
optionsGrowth = plotGrowth();
|
optionsGrowth = plotGrowth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const exportData = (format = "csv") => {
|
||||||
|
// Add headers row
|
||||||
|
const csvRows = [];
|
||||||
|
csvRows.push("Date,Employees,Change,Growth");
|
||||||
|
|
||||||
|
// Add data rows
|
||||||
|
historyList.forEach((item, index) => {
|
||||||
|
const date = new Date(item.filingDate).toLocaleString("en-US", {
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
});
|
||||||
|
|
||||||
|
const employees = item.employeeCount;
|
||||||
|
|
||||||
|
// Calculate change
|
||||||
|
const change =
|
||||||
|
index + 1 < historyList.length
|
||||||
|
? item.employeeCount - historyList[index + 1].employeeCount
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
// Calculate growth percentage
|
||||||
|
let growth = "0.00%";
|
||||||
|
if (index + 1 < historyList.length) {
|
||||||
|
const growthValue =
|
||||||
|
((item.employeeCount - historyList[index + 1].employeeCount) /
|
||||||
|
item.employeeCount) *
|
||||||
|
100;
|
||||||
|
if (growthValue > 0) {
|
||||||
|
growth = `+${growthValue.toFixed(2)}%`;
|
||||||
|
} else if (growthValue < 0) {
|
||||||
|
growth = `-${Math.abs(growthValue).toFixed(2)}%`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const csvRow = `${date},${employees},${change},${growth}`;
|
||||||
|
csvRows.push(csvRow);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create CSV blob and trigger download
|
||||||
|
const csv = csvRows.join("\n");
|
||||||
|
const blob = new Blob([csv], { type: "text/csv" });
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement("a");
|
||||||
|
a.setAttribute("hidden", "");
|
||||||
|
a.setAttribute("href", url);
|
||||||
|
a.setAttribute("download", `${$stockTicker}_employees.csv`);
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<title>
|
<title>
|
||||||
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ''} {$displayCompanyName} ({$stockTicker}) Number of Employees · stocknear
|
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
|
||||||
|
{$displayCompanyName} ({$stockTicker}) Number of Employees · stocknear
|
||||||
</title>
|
</title>
|
||||||
<meta name="description" content={`Detailed historical employees number for ${$displayCompanyName} (${$stockTicker}). See many years of change, growth and the impact.`} />
|
<meta
|
||||||
|
name="description"
|
||||||
|
content={`Detailed historical employees number for ${$displayCompanyName} (${$stockTicker}). See many years of change, growth and the impact.`}
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Other meta tags -->
|
<!-- Other meta tags -->
|
||||||
<meta property="og:title" content={`${$displayCompanyName} (${$stockTicker}) Number of Employees · stocknear`}/>
|
<meta
|
||||||
<meta property="og:description" content={`Detailed historical employees number for ${$displayCompanyName} (${$stockTicker}). See many years of change, growth and the impact.`} />
|
property="og:title"
|
||||||
|
content={`${$displayCompanyName} (${$stockTicker}) Number of Employees · stocknear`}
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content={`Detailed historical employees number for ${$displayCompanyName} (${$stockTicker}). See many years of change, growth and the impact.`}
|
||||||
|
/>
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<!-- Add more Open Graph meta tags as needed -->
|
<!-- Add more Open Graph meta tags as needed -->
|
||||||
|
|
||||||
<!-- Twitter specific meta tags -->
|
<!-- Twitter specific meta tags -->
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="twitter:title" content={`${$displayCompanyName} (${$stockTicker}) Number of Employees · stocknear`}/>
|
<meta
|
||||||
<meta name="twitter:description" content={`Detailed historical employees number for ${$displayCompanyName} (${$stockTicker}). See many years of change, growth and the impact.`} />
|
name="twitter:title"
|
||||||
|
content={`${$displayCompanyName} (${$stockTicker}) Number of Employees · stocknear`}
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
name="twitter:description"
|
||||||
|
content={`Detailed historical employees number for ${$displayCompanyName} (${$stockTicker}). See many years of change, growth and the impact.`}
|
||||||
|
/>
|
||||||
<!-- Add more Twitter meta tags as needed -->
|
<!-- Add more Twitter meta tags as needed -->
|
||||||
|
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="bg-[#09090B] w-full overflow-hidden text-white h-full mb-40 sm:mb-0"
|
||||||
<section class="bg-[#09090B] w-full overflow-hidden text-white h-full mb-40 sm:mb-0">
|
>
|
||||||
<div class="w-full flex justify-center m-auto h-full overflow-hidden">
|
<div class="w-full flex justify-center m-auto h-full overflow-hidden">
|
||||||
<div class="w-full relative flex justify-center items-center overflow-hidden">
|
<div
|
||||||
|
class="w-full relative flex justify-center items-center overflow-hidden"
|
||||||
|
>
|
||||||
<div class="sm:p-7 w-full m-auto mt-2 sm:mt-0">
|
<div class="sm:p-7 w-full m-auto mt-2 sm:mt-0">
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<h2 class="text-2xl sm:text-3xl text-gray-200 font-bold mb-4">
|
<h2 class="text-2xl sm:text-3xl text-gray-200 font-bold mb-4">
|
||||||
Employees
|
Employees
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
<div
|
||||||
<div class="text-white p-3 sm:p-5 mb-5 rounded-lg flex flex-row items-center border border-gray-800 text-sm sm:text-[1rem]">
|
class="text-white p-3 sm:p-5 mb-5 rounded-lg flex flex-row items-center border border-gray-800 text-sm sm:text-[1rem]"
|
||||||
<svg class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><path fill="#a474f6" d="M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24m-4 48a12 12 0 1 1-12 12a12 12 0 0 1 12-12m12 112a16 16 0 0 1-16-16v-40a8 8 0 0 1 0-16a16 16 0 0 1 16 16v40a8 8 0 0 1 0 16"/></svg>
|
>
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
><path
|
||||||
|
fill="#a474f6"
|
||||||
|
d="M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24m-4 48a12 12 0 1 1-12 12a12 12 0 0 1 12-12m12 112a16 16 0 0 1-16-16v-40a8 8 0 0 1 0-16a16 16 0 0 1 16 16v40a8 8 0 0 1 0 16"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
|
||||||
{#if employeeHistory?.length !== 0 && !dateDistance}
|
{#if employeeHistory?.length !== 0 && !dateDistance}
|
||||||
<div>
|
<div>
|
||||||
@ -324,42 +381,72 @@ optionsGrowth = plotGrowth();
|
|||||||
had
|
had
|
||||||
{abbreviateNumber(employees)}
|
{abbreviateNumber(employees)}
|
||||||
employees on
|
employees on
|
||||||
{new Date(employeeHistory[employeeHistory?.length -1]['filingDate'])?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })}.
|
{new Date(
|
||||||
The number of employees {changeRate >=0 ? 'increased' : 'decreased'} by
|
employeeHistory[employeeHistory?.length - 1]["filingDate"],
|
||||||
|
)?.toLocaleString("en-US", {
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
daySuffix: "2-digit",
|
||||||
|
})}. The number of employees {changeRate >= 0
|
||||||
|
? "increased"
|
||||||
|
: "decreased"} by
|
||||||
{abbreviateNumber(changeRate)}
|
{abbreviateNumber(changeRate)}
|
||||||
or
|
or
|
||||||
<span class="{changeRate >=0 ? 'text-[#37C97D]' : 'text-[#FF2F1F]'}">
|
<span
|
||||||
|
class={changeRate >= 0 ? "text-[#37C97D]" : "text-[#FF2F1F]"}
|
||||||
|
>
|
||||||
{growthRate}%
|
{growthRate}%
|
||||||
</span>
|
</span>
|
||||||
compared to the previous year.
|
compared to the previous year.
|
||||||
</div>
|
</div>
|
||||||
{:else if employeeHistory?.length !== 0 && dateDistance}
|
{:else if employeeHistory?.length !== 0 && dateDistance}
|
||||||
{$displayCompanyName} had {abbreviateNumber(employees)} employees on
|
{$displayCompanyName} had {abbreviateNumber(employees)} employees on
|
||||||
{new Date(employeeHistory[employeeHistory?.length -1]['filingDate'])?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })}.
|
{new Date(
|
||||||
Since then, the company has not submitted any additional employee data for more than a year.
|
employeeHistory[employeeHistory?.length - 1]["filingDate"],
|
||||||
|
)?.toLocaleString("en-US", {
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
daySuffix: "2-digit",
|
||||||
|
})}. Since then, the company has not submitted any additional
|
||||||
|
employee data for more than a year.
|
||||||
{:else}
|
{:else}
|
||||||
No employee history for {$displayCompanyName}. Probably, no records of past employees.
|
No employee history for {$displayCompanyName}. Probably, no
|
||||||
|
records of past employees.
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
<div class="mb-4 grid grid-cols-2 grid-rows-1 divide-gray-500 rounded-lg border border-gray-600 bg-[#272727] shadow md:grid-cols-3 md:grid-rows-1 md:divide-x">
|
class="mb-4 grid grid-cols-2 grid-rows-1 divide-gray-500 rounded-lg border border-gray-600 bg-[#272727] shadow md:grid-cols-3 md:grid-rows-1 md:divide-x"
|
||||||
|
>
|
||||||
<div class="p-4 bp:p-5 sm:p-6">
|
<div class="p-4 bp:p-5 sm:p-6">
|
||||||
<label for="totalAnalystInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem]">
|
<label
|
||||||
|
for="totalAnalystInfo"
|
||||||
|
class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem]"
|
||||||
|
>
|
||||||
Total Employees
|
Total Employees
|
||||||
</label>
|
</label>
|
||||||
<div class="mt-1 break-words font-semibold leading-8 text-light text-xl">
|
<div
|
||||||
|
class="mt-1 break-words font-semibold leading-8 text-light text-lg"
|
||||||
|
>
|
||||||
{abbreviateNumber(employees)}
|
{abbreviateNumber(employees)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-4 bp:p-5 sm:p-6 border-l border-b border-contrast md:border-0">
|
<div
|
||||||
<label for="consensusRatingInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem]">
|
class="p-4 bp:p-5 sm:p-6 border-l border-b border-contrast md:border-0"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
for="consensusRatingInfo"
|
||||||
|
class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem]"
|
||||||
|
>
|
||||||
Change (1Y)
|
Change (1Y)
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="mt-1 break-words font-semibold leading-8 text-light text-xl">
|
<div
|
||||||
|
class="mt-1 break-words font-semibold leading-8 text-light text-lg"
|
||||||
|
>
|
||||||
{#if dateDistance}
|
{#if dateDistance}
|
||||||
n/a
|
n/a
|
||||||
{:else}
|
{:else}
|
||||||
@ -367,114 +454,141 @@ optionsGrowth = plotGrowth();
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-4 bp:p-5 sm:p-6 border-t border-r border-contrast md:border-0">
|
<div
|
||||||
<label for="priceTargetInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem]">
|
class="p-4 bp:p-5 sm:p-6 border-t border-r border-contrast md:border-0"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
for="priceTargetInfo"
|
||||||
|
class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem]"
|
||||||
|
>
|
||||||
Growth (1Y)
|
Growth (1Y)
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="mt-1 break-words font-semibold leading-8 text-light text-xl">
|
<div
|
||||||
|
class="mt-1 break-words font-semibold leading-8 text-light text-xl"
|
||||||
|
>
|
||||||
{#if growthRate >= 0}
|
{#if growthRate >= 0}
|
||||||
<span class="text-white text-md font-medium">
|
<span class="text-white text-md font-medium">
|
||||||
<svg class="w-5 h-5 inline-block -mr-1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g id="evaArrowUpFill0"><g id="evaArrowUpFill1"><path id="evaArrowUpFill2" fill="#37C97D" d="M16.21 16H7.79a1.76 1.76 0 0 1-1.59-1a2.1 2.1 0 0 1 .26-2.21l4.21-5.1a1.76 1.76 0 0 1 2.66 0l4.21 5.1A2.1 2.1 0 0 1 17.8 15a1.76 1.76 0 0 1-1.59 1Z"/></g></g></svg>
|
<span class="text-[#37C97D] text-lg">+{growthRate}%</span>
|
||||||
<span class="text-[#37C97D] text-[1rem]">+{growthRate}%</span>
|
|
||||||
</span>
|
</span>
|
||||||
{:else if growthRate < 0}
|
{:else if growthRate < 0}
|
||||||
<div class="text-white text-md font-medium">
|
<div class="text-white text-md font-medium">
|
||||||
<svg class="w-5 h-5 rotate-180 inline-block -mr-1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g id="evaArrowUpFill0"><g id="evaArrowUpFill1"><path id="evaArrowUpFill2" fill="#FF2F1F" d="M16.21 16H7.79a1.76 1.76 0 0 1-1.59-1a2.1 2.1 0 0 1 .26-2.21l4.21-5.1a1.76 1.76 0 0 1 2.66 0l4.21 5.1A2.1 2.1 0 0 1 17.8 15a1.76 1.76 0 0 1-1.59 1Z"/></g></g></svg>
|
<span class="text-[#FF2F1F] text-lg">{growthRate}%</span>
|
||||||
<span class="text-[#FF2F1F] text-[1rem]">{growthRate}%</span>
|
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="text-white m-auto">
|
<span class="text-white m-auto"> n/a </span>
|
||||||
n/a
|
|
||||||
</span>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="flex flex-row items-center w-full mt-10 mb-8">
|
<div class="flex flex-row items-center w-full mt-10 mb-8">
|
||||||
|
<h1 class="text-xl text-white font-semibold">Employees History</h1>
|
||||||
|
|
||||||
<h1 class="text-xl text-white font-semibold ">
|
<div
|
||||||
Employees History
|
class="flex flex-row items-center w-fit sm:w-[50%] md:w-auto ml-auto"
|
||||||
</h1>
|
>
|
||||||
|
|
||||||
|
|
||||||
<div class="flex w-fit sm:w-[50%] md:block md:w-auto ml-auto">
|
|
||||||
<div class="relative inline-block text-left grow">
|
<div class="relative inline-block text-left grow">
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger asChild let:builder>
|
<DropdownMenu.Trigger asChild let:builder>
|
||||||
<Button builders={[builder]} class="w-full border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-lg truncate">
|
<Button
|
||||||
|
builders={[builder]}
|
||||||
|
class="w-full border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-lg truncate"
|
||||||
|
>
|
||||||
<span class="truncate text-white">{sortBy}</span>
|
<span class="truncate text-white">{sortBy}</span>
|
||||||
<svg class="-mr-1 ml-1 h-5 w-5 xs:ml-2 inline-block" viewBox="0 0 20 20" fill="currentColor" style="max-width:40px" aria-hidden="true">
|
<svg
|
||||||
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path>
|
class="-mr-1 ml-1 h-5 w-5 xs:ml-2 inline-block"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
style="max-width:40px"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenu.Trigger>
|
</DropdownMenu.Trigger>
|
||||||
<DropdownMenu.Content class="w-56 h-fit max-h-72 overflow-y-auto scroller">
|
<DropdownMenu.Content
|
||||||
|
class="w-56 h-fit max-h-72 overflow-y-auto scroller"
|
||||||
|
>
|
||||||
<DropdownMenu.Label class="text-gray-400">
|
<DropdownMenu.Label class="text-gray-400">
|
||||||
Select Type
|
Select Type
|
||||||
</DropdownMenu.Label>
|
</DropdownMenu.Label>
|
||||||
<DropdownMenu.Separator />
|
<DropdownMenu.Separator />
|
||||||
<DropdownMenu.Group>
|
<DropdownMenu.Group>
|
||||||
<DropdownMenu.Item on:click={() => sortBy = 'Total'} class="cursor-pointer hover:bg-[#27272A]">
|
<DropdownMenu.Item
|
||||||
|
on:click={() => (sortBy = "Total")}
|
||||||
|
class="cursor-pointer hover:bg-[#27272A]"
|
||||||
|
>
|
||||||
Total
|
Total
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item on:click={() => sortBy = 'Change'} class="cursor-pointer hover:bg-[#27272A]">
|
<DropdownMenu.Item
|
||||||
|
on:click={() => (sortBy = "Change")}
|
||||||
|
class="cursor-pointer hover:bg-[#27272A]"
|
||||||
|
>
|
||||||
Change
|
Change
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item on:click={() => sortBy = 'Growth'} class="cursor-pointer hover:bg-[#27272A]">
|
<DropdownMenu.Item
|
||||||
|
on:click={() => (sortBy = "Growth")}
|
||||||
|
class="cursor-pointer hover:bg-[#27272A]"
|
||||||
|
>
|
||||||
Growth
|
Growth
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
</DropdownMenu.Group>
|
</DropdownMenu.Group>
|
||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
on:click={() => exportData("csv")}
|
||||||
|
class="ml-2 w-full border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-lg truncate"
|
||||||
|
>
|
||||||
|
<span class="truncate text-white">Download</span>
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{#if historyList?.length !== 0}
|
{#if historyList?.length !== 0}
|
||||||
|
{#if sortBy === "Total"}
|
||||||
|
|
||||||
{#if sortBy === 'Total'}
|
|
||||||
<div class="app w-full">
|
<div class="app w-full">
|
||||||
<Chart {init} options={optionsTotal} class="chart" />
|
<Chart {init} options={optionsTotal} class="chart" />
|
||||||
</div>
|
</div>
|
||||||
{:else if sortBy === 'Change'}
|
{:else if sortBy === "Change"}
|
||||||
<div class="app w-full">
|
<div class="app w-full">
|
||||||
<Chart {init} options={optionsChange} class="chart" />
|
<Chart {init} options={optionsChange} class="chart" />
|
||||||
</div>
|
</div>
|
||||||
{:else if sortBy === 'Growth'}
|
{:else if sortBy === "Growth"}
|
||||||
<div class="app w-full">
|
<div class="app w-full">
|
||||||
<Chart {init} options={optionsGrowth} class="chart" />
|
<Chart {init} options={optionsGrowth} class="chart" />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="w-full overflow-x-scroll">
|
<div class="w-full overflow-x-scroll">
|
||||||
<table class="table table-sm table-compact rounded-none sm:rounded-md w-full border-bg-[#09090B] m-auto mt-4 ">
|
<table
|
||||||
|
class="table table-sm table-compact rounded-none sm:rounded-md w-full border-bg-[#09090B] m-auto mt-4"
|
||||||
|
>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-start border-b border-[#09090B] bg-[#09090B] text-white text-[1rem] whitespace-nowrap font-semibiold">
|
<th
|
||||||
|
class="text-start border-b border-[#09090B] bg-[#09090B] text-white text-[1rem] whitespace-nowrap font-semibiold"
|
||||||
|
>
|
||||||
Date
|
Date
|
||||||
</th>
|
</th>
|
||||||
<th class="text-end border-b border-[#09090B] bg-[#09090B] text-white text-[1rem] whitespace-nowrap font-semibiold">
|
<th
|
||||||
|
class="text-end border-b border-[#09090B] bg-[#09090B] text-white text-[1rem] whitespace-nowrap font-semibiold"
|
||||||
|
>
|
||||||
Employees
|
Employees
|
||||||
</th>
|
</th>
|
||||||
<th class="text-end border-b border-[#09090B] bg-[#09090B] text-white text-[1rem] whitespace-nowrap font-semibiold">
|
<th
|
||||||
|
class="text-end border-b border-[#09090B] bg-[#09090B] text-white text-[1rem] whitespace-nowrap font-semibiold"
|
||||||
|
>
|
||||||
Change
|
Change
|
||||||
</th>
|
</th>
|
||||||
<th class="text-end border-b border-[#09090B] bg-[#09090B] text-white text-[1rem] whitespace-nowrap font-semibiold">
|
<th
|
||||||
|
class="text-end border-b border-[#09090B] bg-[#09090B] text-white text-[1rem] whitespace-nowrap font-semibiold"
|
||||||
|
>
|
||||||
Growth
|
Growth
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -482,60 +596,73 @@ optionsGrowth = plotGrowth();
|
|||||||
<tbody class="">
|
<tbody class="">
|
||||||
{#each historyList as item, index}
|
{#each historyList as item, index}
|
||||||
<tr class="text-gray-200 odd:bg-[#27272A]">
|
<tr class="text-gray-200 odd:bg-[#27272A]">
|
||||||
<td class="text-start border-b border-[#09090B] text-sm sm:text-[1rem] whitespace-nowrap text-white">
|
<td
|
||||||
{new Date(item?.filingDate)?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })}
|
class="text-start border-b border-[#09090B] text-sm sm:text-[1rem] whitespace-nowrap text-white"
|
||||||
|
>
|
||||||
|
{new Date(item?.filingDate)?.toLocaleString("en-US", {
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
daySuffix: "2-digit",
|
||||||
|
})}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end border-b border-[#09090B] text-sm sm:text-[1rem] whitespace-nowrap text-white">
|
<td
|
||||||
|
class="text-end border-b border-[#09090B] text-sm sm:text-[1rem] whitespace-nowrap text-white"
|
||||||
|
>
|
||||||
{new Intl.NumberFormat("en").format(item?.employeeCount)}
|
{new Intl.NumberFormat("en").format(item?.employeeCount)}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end border-b border-[#09090B] text-sm sm:text-[1rem] whitespace-nowrap text-white">
|
<td
|
||||||
{abbreviateNumber(item?.employeeCount-historyList[index+1]?.employeeCount)}
|
class="text-end border-b border-[#09090B] text-sm sm:text-[1rem] whitespace-nowrap text-white"
|
||||||
|
>
|
||||||
|
{abbreviateNumber(
|
||||||
|
item?.employeeCount -
|
||||||
|
historyList[index + 1]?.employeeCount,
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end border-b border-[#09090B] text-sm sm:text-[1rem] whitespace-nowrap text-white text-end">
|
<td
|
||||||
|
class="text-end border-b border-[#09090B] text-sm sm:text-[1rem] whitespace-nowrap text-white text-end"
|
||||||
|
>
|
||||||
{#if index + 1 - historyList?.length === 0}
|
{#if index + 1 - historyList?.length === 0}
|
||||||
0.00%
|
0.00%
|
||||||
{:else}
|
{:else if item?.employeeCount - historyList[index + 1]?.employeeCount > 0}
|
||||||
{#if (item?.employeeCount- historyList[index+1]?.employeeCount) > 0}
|
|
||||||
<span class="text-[#37C97D]">
|
<span class="text-[#37C97D]">
|
||||||
+{(((item?.employeeCount-historyList[index+1]?.employeeCount) / item?.employeeCount) * 100 )?.toFixed(2)}%
|
+{(
|
||||||
|
((item?.employeeCount -
|
||||||
|
historyList[index + 1]?.employeeCount) /
|
||||||
|
item?.employeeCount) *
|
||||||
|
100
|
||||||
|
)?.toFixed(2)}%
|
||||||
</span>
|
</span>
|
||||||
{:else if (item?.employeeCount - historyList[index+1]?.employeeCount ) < 0}
|
{:else if item?.employeeCount - historyList[index + 1]?.employeeCount < 0}
|
||||||
<span class="text-[#FF2F1F]">
|
<span class="text-[#FF2F1F]">
|
||||||
-{(((historyList[index+1]?.employeeCount - item?.employeeCount) / item?.employeeCount) * 100 )?.toFixed(2)}%
|
-{(
|
||||||
|
((historyList[index + 1]?.employeeCount -
|
||||||
|
item?.employeeCount) /
|
||||||
|
item?.employeeCount) *
|
||||||
|
100
|
||||||
|
)?.toFixed(2)}%
|
||||||
</span>
|
</span>
|
||||||
{:else}
|
{:else}
|
||||||
0.00%
|
0.00%
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
<h1 class="text-xl m-auto flex justify-center text-gray-200 font-medium mb-4 mt-10">
|
<h1
|
||||||
|
class="text-xl m-auto flex justify-center text-gray-200 font-medium mb-4 mt-10"
|
||||||
|
>
|
||||||
No history found
|
No history found
|
||||||
</h1>
|
</h1>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.app {
|
.app {
|
||||||
height: 400px;
|
height: 400px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user