update chart
This commit is contained in:
parent
4d49db2bd4
commit
957dd1dfca
@ -12,24 +12,11 @@
|
|||||||
} from "$lib/utils";
|
} from "$lib/utils";
|
||||||
import highcharts from "$lib/highcharts.ts";
|
import highcharts from "$lib/highcharts.ts";
|
||||||
|
|
||||||
import { Chart } from "svelte-echarts";
|
|
||||||
import { init, use } from "echarts/core";
|
|
||||||
import { LineChart, BarChart, GaugeChart } from "echarts/charts";
|
|
||||||
import { GridComponent, TooltipComponent } from "echarts/components";
|
|
||||||
import { CanvasRenderer } from "echarts/renderers";
|
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
|
|
||||||
import SEO from "$lib/components/SEO.svelte";
|
import SEO from "$lib/components/SEO.svelte";
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
use([
|
|
||||||
LineChart,
|
|
||||||
GaugeChart,
|
|
||||||
BarChart,
|
|
||||||
GridComponent,
|
|
||||||
TooltipComponent,
|
|
||||||
CanvasRenderer,
|
|
||||||
]);
|
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let changeRevenue = 0;
|
let changeRevenue = 0;
|
||||||
@ -103,7 +90,7 @@
|
|||||||
categories = ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"];
|
categories = ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"];
|
||||||
}
|
}
|
||||||
|
|
||||||
optionsData = getPlotOptions() || null;
|
optionsBarChart = getPlotOptions() || null;
|
||||||
optionsPieChart = getPieChart() || null;
|
optionsPieChart = getPieChart() || null;
|
||||||
config = getPriceForecastChart() || null;
|
config = getPriceForecastChart() || null;
|
||||||
}
|
}
|
||||||
@ -151,88 +138,113 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function getPlotOptions() {
|
function getBarChart() {
|
||||||
if (!rawAnalystList || rawAnalystList.length === 0) {
|
if (!rawAnalystList || rawAnalystList.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define categories in the exact order you specified
|
const categories = ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"];
|
||||||
const categories = ["Strong Sell", "Sell", "Hold", "Buy", "Strong Buy"];
|
const colors = ["#008A00", "#31B800", "#F5B700", "#D9220E", "#9E190A"];
|
||||||
const colors = ["#9E190A", "#D9220E", "#f5b700", "#31B800", "#008A00"];
|
|
||||||
|
|
||||||
// Create a consistent mapping for data
|
// Step 1: Store original values
|
||||||
const formattedData = rawAnalystList?.map((item) =>
|
const formattedData = rawAnalystList.map((item) =>
|
||||||
categories.map((cat) => item[cat] || 0),
|
categories.map((cat) => item[cat] || 0),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Normalize data to percentages
|
// Step 2: Create normalized data for visualization
|
||||||
const normalizedData = formattedData.map((row) => {
|
const normalizedData = formattedData.map((row) => {
|
||||||
const total = row.reduce((sum, val) => sum + val, 0);
|
const total = row.reduce((sum, val) => sum + val, 0);
|
||||||
return row.map((val) => (total > 0 ? (val / total) * 100 : 0));
|
return row.map((val) => (total > 0 ? (val / total) * 100 : 0));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Calculate total percentage for each category across all dates
|
// Step 3: Include original values in data points
|
||||||
const totalData = [];
|
|
||||||
for (let i = 0; i < categories.length; ++i) {
|
|
||||||
let sum = 0;
|
|
||||||
for (let j = 0; j < normalizedData.length; ++j) {
|
|
||||||
sum += normalizedData[j][i];
|
|
||||||
}
|
|
||||||
totalData.push(sum / normalizedData.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define series based on categories with color mapping
|
|
||||||
const series = categories.map((name, idx) => ({
|
const series = categories.map((name, idx) => ({
|
||||||
name,
|
name: name,
|
||||||
type: "bar",
|
data: normalizedData?.map((row, dataIndex) => ({
|
||||||
stack: "total",
|
y: formattedData[dataIndex][idx], // Normalized percentage for chart
|
||||||
barWidth: "60%",
|
originalValue: formattedData[dataIndex][idx], // Original value for tooltip
|
||||||
data: normalizedData.map((row) => row[idx]),
|
})),
|
||||||
itemStyle: {
|
color: colors[idx],
|
||||||
color: colors[idx],
|
borderColor: colors[idx],
|
||||||
},
|
borderRadius: "1px",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Define chart option
|
const xCategories = rawAnalystList.map((item) => {
|
||||||
const option = {
|
const dateParts = item?.date?.split("-");
|
||||||
grid: {
|
const year = dateParts[0];
|
||||||
left: "2%",
|
const monthIndex = parseInt(dateParts[1], 10) - 1;
|
||||||
right: "2%",
|
return `${monthNames[monthIndex]} ${year}`;
|
||||||
bottom: "10%",
|
});
|
||||||
top: "5%",
|
|
||||||
containLabel: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
|
// Define and return the Highcharts options object
|
||||||
|
const options = {
|
||||||
|
chart: {
|
||||||
|
type: "column",
|
||||||
|
backgroundColor: "#09090B",
|
||||||
|
plotBackgroundColor: "#09090B",
|
||||||
|
animation: false,
|
||||||
|
height: 360, // Add fixed height
|
||||||
|
marginTop: 40, // Reduce top margin
|
||||||
|
marginBottom: 60, // Increase bottom margin for x-axis labels
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: null,
|
||||||
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: "category",
|
categories: xCategories,
|
||||||
data: rawAnalystList.map((item) => item.date),
|
labels: {
|
||||||
axisLabel: {
|
style: {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
formatter: function (value) {
|
|
||||||
const dateParts = value.split("-");
|
|
||||||
const year = dateParts[0].substring(0);
|
|
||||||
const monthIndex = parseInt(dateParts[1]) - 1;
|
|
||||||
return `${monthNames[monthIndex]} ${year}`;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
yAxis: {
|
tooltip: {
|
||||||
type: "value",
|
shared: true,
|
||||||
max: 100,
|
useHTML: true,
|
||||||
|
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
||||||
axisLabel: {
|
borderColor: "rgba(255, 255, 255, 0.2)",
|
||||||
show: false, // Hide y-axis labels
|
borderWidth: 1,
|
||||||
|
style: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: "16px",
|
||||||
|
padding: "10px",
|
||||||
},
|
},
|
||||||
splitLine: {
|
borderRadius: 4,
|
||||||
show: false,
|
headerFormat:
|
||||||
|
'<span class="font-semibold text-[1rem]">{point.key}</span><br/>',
|
||||||
|
pointFormat:
|
||||||
|
'<span style="color:{point.color}">\u25CF</span> ' +
|
||||||
|
"<span class='text-sm'>{series.name}: <b>{point.originalValue}</b><br/></span>",
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
gridLineWidth: 1,
|
||||||
|
gridLineColor: "#111827",
|
||||||
|
labels: {
|
||||||
|
style: { color: "white" },
|
||||||
|
},
|
||||||
|
title: { text: null },
|
||||||
|
},
|
||||||
|
plotOptions: {
|
||||||
|
column: {
|
||||||
|
stacking: "normal", // stacks the columns so that each column adds up to 100%
|
||||||
|
pointWidth: 40, // adjust this value as needed to mimic your desired "barWidth"
|
||||||
|
pointPadding: 0.1, // More spacing between bars
|
||||||
|
groupPadding: 0.1, // More spacing between groups
|
||||||
|
},
|
||||||
|
series: {
|
||||||
|
animation: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
series,
|
credits: {
|
||||||
animation: false,
|
enabled: false,
|
||||||
silent: true,
|
},
|
||||||
|
series: series,
|
||||||
};
|
};
|
||||||
|
|
||||||
return option;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPieChart() {
|
function getPieChart() {
|
||||||
@ -680,7 +692,7 @@
|
|||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
let optionsData = getPlotOptions() || null;
|
let optionsBarChart = getBarChart() || null;
|
||||||
let optionsPieChart = getPieChart() || null;
|
let optionsPieChart = getPieChart() || null;
|
||||||
let config = getPriceForecastChart() || null;
|
let config = getPriceForecastChart() || null;
|
||||||
|
|
||||||
@ -921,11 +933,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grow pt-2 md:pt-4 lg:pl-4 lg:pt-0">
|
<div class="grow pt-2 md:pt-4 lg:pl-4 lg:pt-0">
|
||||||
<div class="app h-[250px] xs:h-[275px]">
|
{#if optionsBarChart !== null}
|
||||||
{#if optionsData !== null}
|
<div
|
||||||
<Chart {init} options={optionsData} class="chart" />
|
class="border border-gray-800 rounded"
|
||||||
{/if}
|
use:highcharts={optionsBarChart}
|
||||||
</div>
|
></div>
|
||||||
|
{/if}
|
||||||
<div
|
<div
|
||||||
class="hide-scroll mb-1 mt-2 overflow-x-auto px-1.5 text-center md:mb-0 md:px-0 lg:mt-2"
|
class="hide-scroll mb-1 mt-2 overflow-x-auto px-1.5 text-center md:mb-0 md:px-0 lg:mt-2"
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user