update the styles in interactive bar chart , also finisht the shematic
This commit is contained in:
parent
2c393eddf0
commit
19b3409572
|
|
@ -1,5 +1,4 @@
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React from "react";
|
||||||
import * as d3 from "d3";
|
|
||||||
import { formatNumber } from "~/lib/utils";
|
import { formatNumber } from "~/lib/utils";
|
||||||
|
|
||||||
export type CompanyInfo = {
|
export type CompanyInfo = {
|
||||||
|
|
@ -17,141 +16,162 @@ export type D3ImageInfoProps = {
|
||||||
height?: number;
|
height?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function D3ImageInfo({ companies, width = 900, height = 400 }: D3ImageInfoProps) {
|
const InfoBox = ({ company, style }: { company: CompanyInfo; style :any }) => {
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
||||||
const svgRef = useRef<SVGSVGElement | null>(null);
|
|
||||||
|
|
||||||
const draw = () => {
|
|
||||||
if (!containerRef.current || !svgRef.current) return;
|
|
||||||
|
|
||||||
const container = containerRef.current;
|
|
||||||
const svg = d3.select(svgRef.current);
|
|
||||||
|
|
||||||
const W = Math.max(480, container.clientWidth || width);
|
|
||||||
const H = Math.max(300, height);
|
|
||||||
|
|
||||||
svg.attr("width", W).attr("height", H);
|
|
||||||
|
|
||||||
svg.selectAll("*").remove();
|
|
||||||
|
|
||||||
const padding = 10;
|
|
||||||
const cols = 3;
|
|
||||||
const rows = 2;
|
|
||||||
const boxWidth = (W - padding * (cols + 1)) / cols;
|
|
||||||
const boxHeight = (H - padding * (rows + 1)) / rows;
|
|
||||||
|
|
||||||
const group = svg.append("g").attr("transform", `translate(${padding}, ${padding})`);
|
|
||||||
|
|
||||||
companies.forEach((company, i) => {
|
|
||||||
const col = i % cols;
|
|
||||||
const row = Math.floor(i / cols);
|
|
||||||
const x = col * (boxWidth + padding);
|
|
||||||
const y = row * (boxHeight + padding);
|
|
||||||
|
|
||||||
const companyGroup = group.append("g").attr("transform", `translate(${x}, ${y})`);
|
|
||||||
|
|
||||||
// Draw background box
|
|
||||||
companyGroup
|
|
||||||
.append("rect")
|
|
||||||
.attr("width", boxWidth)
|
|
||||||
.attr("height", boxHeight)
|
|
||||||
.attr("rx", 10)
|
|
||||||
.attr("ry", 10)
|
|
||||||
.attr("fill", "transparent")
|
|
||||||
|
|
||||||
// Draw image
|
|
||||||
const imgSize = Math.min(boxWidth, boxHeight) * 0.5;
|
|
||||||
companyGroup
|
|
||||||
.append("image")
|
|
||||||
.attr("href", company.imageUrl)
|
|
||||||
.attr("x", 10)
|
|
||||||
.attr("y", 10)
|
|
||||||
.attr("width", imgSize)
|
|
||||||
.attr("height", imgSize)
|
|
||||||
.attr("preserveAspectRatio", "xMidYMid slice")
|
|
||||||
.style("background", "transparent");
|
|
||||||
|
|
||||||
// Adjust positions to match picture
|
|
||||||
// Position image slightly left and info box to right with spacing
|
|
||||||
const infoX = imgSize + 30;
|
|
||||||
const infoY = 10;
|
|
||||||
const infoWidth = 120;
|
|
||||||
const infoHeight = imgSize;
|
|
||||||
|
|
||||||
const infoGroup = companyGroup.append("g");
|
|
||||||
|
|
||||||
infoGroup
|
|
||||||
.append("rect")
|
|
||||||
.attr("x", infoX)
|
|
||||||
.attr("y", infoY)
|
|
||||||
.attr("width", infoWidth)
|
|
||||||
.attr("height", infoHeight)
|
|
||||||
.attr("rx", 10)
|
|
||||||
.attr("ry", 10)
|
|
||||||
.attr("fill", "transparent")
|
|
||||||
.attr("stroke", "#3F415A")
|
|
||||||
.attr("stroke-width", 1);
|
|
||||||
|
|
||||||
// Add text inside info box
|
|
||||||
const lineHeight = 20;
|
|
||||||
infoGroup
|
|
||||||
.append("text")
|
|
||||||
.attr("x", imgSize + 10 )
|
|
||||||
.attr("y", infoY + imgSize + 10)
|
|
||||||
.attr("fill", "#FFFFFF")
|
|
||||||
.attr("font-weight", "700")
|
|
||||||
.attr("font-size", 14)
|
|
||||||
.text(company.name);
|
|
||||||
|
|
||||||
infoGroup
|
|
||||||
.append("text")
|
|
||||||
.attr("x", infoX + imgSize)
|
|
||||||
.attr("y", infoY + lineHeight )
|
|
||||||
.attr("fill", "#FFFFFF")
|
|
||||||
.attr("font-size", 12)
|
|
||||||
.text(`درآمد: ${formatNumber(company?.revenue || "0")}`);
|
|
||||||
infoGroup
|
|
||||||
.append("text")
|
|
||||||
.attr("x", infoX + imgSize -20 )
|
|
||||||
.attr("y", infoY + lineHeight +5 )
|
|
||||||
.attr("fill", "#ACACAC")
|
|
||||||
.attr("font-size", 6)
|
|
||||||
.text(`میلیون ریال`);
|
|
||||||
|
|
||||||
|
|
||||||
infoGroup
|
|
||||||
.append("text")
|
|
||||||
.attr("x", infoX + imgSize)
|
|
||||||
.attr("y", infoY + lineHeight *2 )
|
|
||||||
.attr("fill", "#FFFFFF")
|
|
||||||
.attr("font-size", 12)
|
|
||||||
.text(`هزینه: ${formatNumber(company?.cost || "0")} میلیون ریال`);
|
|
||||||
|
|
||||||
infoGroup
|
|
||||||
.append("text")
|
|
||||||
.attr("x", infoX + imgSize)
|
|
||||||
.attr("y", infoY + lineHeight * 3 )
|
|
||||||
.attr("fill", "#FFFFFF")
|
|
||||||
.attr("font-size", 12)
|
|
||||||
.text(`ظرفیت: ${formatNumber(company?.capacity || "0")} تن در سال`);
|
|
||||||
|
|
||||||
// Remove click handlers and popup
|
|
||||||
companyGroup.style("cursor", "default");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
draw();
|
|
||||||
const ro = new ResizeObserver(() => draw());
|
|
||||||
if (containerRef.current) ro.observe(containerRef.current);
|
|
||||||
return () => ro.disconnect();
|
|
||||||
}, [companies, width, height]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full">
|
<div className={`info-box`} style={style}>
|
||||||
<div ref={containerRef} className="w-full h-[400px]">
|
<div className="info-box-content">
|
||||||
<svg ref={svgRef} className="block w-full h-full"></svg>
|
<div className="info-row">
|
||||||
|
<div className="info-label">درآمد:</div>
|
||||||
|
<div className="info-value revenue">{formatNumber(company?.revenue || 0)}</div>
|
||||||
|
<div className="info-unit">میلیون ریال</div>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<div className="info-label">هزینه:</div>
|
||||||
|
<div className="info-value cost">{formatNumber(company?.cost || 0)}</div>
|
||||||
|
<div className="info-unit">میلیون ریال</div>
|
||||||
|
</div>
|
||||||
|
<div className="info-row">
|
||||||
|
<div className="info-label">ظرفیت:</div>
|
||||||
|
<div className="info-value capacity">{formatNumber(company?.capacity || 0)}</div>
|
||||||
|
<div className="info-unit">تن در سال</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function D3ImageInfo({ companies }: D3ImageInfoProps) {
|
||||||
|
// Ensure we have exactly 6 companies
|
||||||
|
const displayCompanies = companies;
|
||||||
|
|
||||||
|
// Positions inside a 5x4 grid (col, row)
|
||||||
|
// Layout keeps same visual logic: left/middle/right on two bands with spacing grid around
|
||||||
|
const gridPositions = [
|
||||||
|
{ col: 2, row: 2 , colI : 1 , rowI : 2 , name : "بسپاران"}, // left - top band
|
||||||
|
{ col: 3, row: 2 , colI : 3 , rowI : 1 , name : "خوارزمی"}, // middle top (image sits in row 2, info box goes to row 1)
|
||||||
|
{ col: 4, row: 2 ,colI : 5 , rowI : 2 , name : "فراورش 1"}, // right - top band
|
||||||
|
{ col: 2, row: 3 , colI : 1 , rowI : 3 , name : "کیمیا"}, // left - bottom band
|
||||||
|
{ col: 3, row: 3 , colI : 3, rowI : 4 , name : "آب نیرو"}, // middle bottom (image sits in row 3, info box goes to row 4)
|
||||||
|
{ col: 4, row: 3 , colI : 5 , rowI : 3 , name : "فراورش 2"}, // right - bottom band
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full h-[500px] rounded-xl p-4">
|
||||||
|
<div dir="ltr" className="company-grid-container">
|
||||||
|
{displayCompanies.map((company, index) => {
|
||||||
|
const gp = gridPositions.find(v => v.name === company.name) || { col: (index % 5) + 1, row: Math.floor(index / 5) + 1 };
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
key={company.id}
|
||||||
|
className={`company-item`}
|
||||||
|
style={{ gridColumn: gp.col, gridRow: gp.row }}
|
||||||
|
>
|
||||||
|
<div className="company-image-containe">
|
||||||
|
<img
|
||||||
|
src={company.imageUrl}
|
||||||
|
alt={company.name}
|
||||||
|
className="company-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{company.name}
|
||||||
|
</div>
|
||||||
|
<InfoBox company={company} key={index +10} style={{ gridColumn: gp.colI , gridRow: gp.rowI }} />
|
||||||
|
</>);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style jsx>{`
|
||||||
|
.company-grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
grid-template-rows: repeat(4, 1fr);
|
||||||
|
gap: 5px;
|
||||||
|
width: 100%;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-item {
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-image-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.company-image {
|
||||||
|
object-fit: contain;
|
||||||
|
height : 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
border: 1px solid #3F415A;
|
||||||
|
border-radius: 10px;
|
||||||
|
height: max-content;
|
||||||
|
align-self : center;
|
||||||
|
justify-self : center;
|
||||||
|
padding : .2rem 0 ;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.info-box-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-row {
|
||||||
|
position : relative;
|
||||||
|
margin: 0rem 1rem;
|
||||||
|
display: flex;
|
||||||
|
gap : 1rem;
|
||||||
|
justify-content : space-between;
|
||||||
|
padding: 0rem .8rem;
|
||||||
|
direction: rtl;
|
||||||
|
|
||||||
|
&:has(.info-value.revenue) {border-bottom: 1px solid #3AEA83;}
|
||||||
|
&:has(.info-value.cost) {border-bottom: 1px solid #F76276;}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
color: #34D399;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: right;
|
||||||
|
margin-bottom : .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value.revenue { color: #fff;}
|
||||||
|
.info-value.cost { color: #fff; }
|
||||||
|
.info-value.capacity { color: #fff; }
|
||||||
|
|
||||||
|
.info-unit {
|
||||||
|
position: absolute;
|
||||||
|
left: 12px;
|
||||||
|
bottom: 0;
|
||||||
|
color: #9CA3AF;
|
||||||
|
font-size: 8px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ export function DashboardCustomBarChart({
|
||||||
<span className="text-white font-bold text-base">
|
<span className="text-white font-bold text-base">
|
||||||
{formatNumber(item.value)}
|
{formatNumber(item.value)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-white font-persian font-medium text-sm w-max">
|
<span className="text-[#3F415A] font-persian font-medium text-sm w-max">
|
||||||
{item.label}
|
{item.label}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -126,19 +126,19 @@ export function DashboardHome() {
|
||||||
let incCapacityTotal = 0;
|
let incCapacityTotal = 0;
|
||||||
const chartRows = rows.map((r) => {
|
const chartRows = rows.map((r) => {
|
||||||
const rel = r?.related_company ?? "-";
|
const rel = r?.related_company ?? "-";
|
||||||
const preFee = Number(r?.pre_innovation_fee_sum ?? 0);
|
const preFee = Number(r?.pre_innovation_fee_sum ?? 0) > 0 ? r?.pre_innovation_fee_sum : 0;
|
||||||
const costRed = Number(r?.innovation_cost_reduction_sum ?? 0);
|
const costRed = Number(r?.innovation_cost_reduction_sum ?? 0) > 0 ? r?.innovation_cost_reduction_sum : 0;
|
||||||
const preCap = Number(r?.pre_project_production_capacity_sum ?? 0);
|
const preCap = Number(r?.pre_project_production_capacity_sum ?? 0) > 0 ? r?.pre_project_production_capacity_sum : 0;
|
||||||
const incCap = Number(r?.increased_capacity_after_innovation_sum ?? 0);
|
const incCap = Number(r?.increased_capacity_after_innovation_sum ?? 0) > 0 ? r?.increased_capacity_after_innovation_sum : 0;
|
||||||
const preInc = Number(r?.pre_project_income_sum ?? 0);
|
const preInc = Number(r?.pre_project_income_sum ?? 0) > 0 ? r?.pre_project_income_sum : 0;
|
||||||
const incInc = Number(r?.increased_income_after_innovation_sum ?? 0);
|
const incInc = Number(r?.increased_income_after_innovation_sum ?? 0) > 0 ? r?.increased_income_after_innovation_sum : 0;
|
||||||
|
|
||||||
incCapacityTotal += incCap;
|
incCapacityTotal += incCap;
|
||||||
|
|
||||||
const capacityPct = preCap > 0 ? (incCap / preCap) * 100 : 0;
|
const capacityPct = preCap > 0 ? (incCap / preCap) * 100 : 0;
|
||||||
const revenuePct = preInc > 0 ? (incInc / preInc) * 100 : 0;
|
const revenuePct = preInc > 0 ? (incInc / preInc) * 100 : 0;
|
||||||
const costPct = preFee > 0 ? (costRed / preFee) * 100 : 0;
|
const costPct = preFee > 0 ? (costRed / preFee) * 100 : 0;
|
||||||
|
console.log(costRed)
|
||||||
return {
|
return {
|
||||||
category: rel,
|
category: rel,
|
||||||
capacity: isFinite(capacityPct) ? capacityPct : 0,
|
capacity: isFinite(capacityPct) ? capacityPct : 0,
|
||||||
|
|
@ -475,7 +475,7 @@ export function DashboardHome() {
|
||||||
<div className="flex items-center justify-center flex-col">
|
<div className="flex items-center justify-center flex-col">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="text-5xl font-bold text-green-400">
|
<p className="text-4xl font-bold text-green-400">
|
||||||
{formatNumber(
|
{formatNumber(
|
||||||
dashboardData.topData
|
dashboardData.topData
|
||||||
?.technology_innovation_based_revenue_growth || "0",
|
?.technology_innovation_based_revenue_growth || "0",
|
||||||
|
|
@ -487,7 +487,7 @@ export function DashboardHome() {
|
||||||
</div>
|
</div>
|
||||||
<span className="text-6xl font-thin text-gray-600">/</span>
|
<span className="text-6xl font-thin text-gray-600">/</span>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="text-5xl font-bold text-green-400">
|
<p className="text-4xl font-bold text-green-400">
|
||||||
{formatNumber(
|
{formatNumber(
|
||||||
Math.round(
|
Math.round(
|
||||||
dashboardData.topData
|
dashboardData.topData
|
||||||
|
|
@ -518,7 +518,7 @@ export function DashboardHome() {
|
||||||
<div className="flex items-center justify-center flex-col">
|
<div className="flex items-center justify-center flex-col">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="text-5xl font-bold text-green-400">
|
<p className="text-4xl font-bold text-green-400">
|
||||||
{formatNumber(
|
{formatNumber(
|
||||||
Math.round(
|
Math.round(
|
||||||
parseFloat(
|
parseFloat(
|
||||||
|
|
@ -536,7 +536,7 @@ export function DashboardHome() {
|
||||||
</div>
|
</div>
|
||||||
<span className="text-6xl font-thin text-gray-600">/</span>
|
<span className="text-6xl font-thin text-gray-600">/</span>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className="text-5xl font-bold text-green-400">
|
<p className="text-4xl font-bold text-green-400">
|
||||||
{formatNumber(
|
{formatNumber(
|
||||||
Math.round(
|
Math.round(
|
||||||
dashboardData.topData
|
dashboardData.topData
|
||||||
|
|
@ -642,7 +642,7 @@ export function DashboardHome() {
|
||||||
</ChartContainer>
|
</ChartContainer>
|
||||||
<div className="font-bold font-persian text-center">
|
<div className="font-bold font-persian text-center">
|
||||||
<div className="flex flex-col justify-between items-center gap-2">
|
<div className="flex flex-col justify-between items-center gap-2">
|
||||||
<span className="flex font-bold items-center gap-1">
|
<span className="flex font-bold items-center gap-1 mr-auto">
|
||||||
<div className="font-light">مصوب :</div>
|
<div className="font-light">مصوب :</div>
|
||||||
{formatNumber(
|
{formatNumber(
|
||||||
Math.round(
|
Math.round(
|
||||||
|
|
@ -655,7 +655,7 @@ export function DashboardHome() {
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex items-center gap-1 font-bold">
|
<span className="flex items-center gap-1 font-bold mr-auto">
|
||||||
<div className="font-light">جذب شده :</div>
|
<div className="font-light">جذب شده :</div>
|
||||||
{formatNumber(
|
{formatNumber(
|
||||||
Math.round(
|
Math.round(
|
||||||
|
|
@ -700,7 +700,7 @@ export function DashboardHome() {
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="canvas" className="w-ful h-full">
|
<TabsContent value="canvas" className="w-ful h-full">
|
||||||
<div className="p-4">
|
<div className="p-4 h-full">
|
||||||
<D3ImageInfo
|
<D3ImageInfo
|
||||||
companies={
|
companies={
|
||||||
companyChartData.map((item) => {
|
companyChartData.map((item) => {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import {
|
||||||
type ChartConfig,
|
type ChartConfig,
|
||||||
ChartContainer,
|
ChartContainer,
|
||||||
} from "~/components/ui/chart";
|
} from "~/components/ui/chart";
|
||||||
|
import { formatNumber } from "~/lib/utils";
|
||||||
|
|
||||||
export type CompanyChartDatum = {
|
export type CompanyChartDatum = {
|
||||||
category: string; // related_company
|
category: string; // related_company
|
||||||
|
|
@ -22,7 +23,7 @@ export type CompanyChartDatum = {
|
||||||
const chartConfig = {
|
const chartConfig = {
|
||||||
capacity: {
|
capacity: {
|
||||||
label: "افزایش ظرفیت",
|
label: "افزایش ظرفیت",
|
||||||
color: "#60A5FA", // Blue-400
|
color: "#69C8EA",
|
||||||
},
|
},
|
||||||
revenue: {
|
revenue: {
|
||||||
label: "افزایش درآمد",
|
label: "افزایش درآمد",
|
||||||
|
|
@ -34,6 +35,7 @@ const chartConfig = {
|
||||||
},
|
},
|
||||||
} satisfies ChartConfig;
|
} satisfies ChartConfig;
|
||||||
|
|
||||||
|
|
||||||
export function InteractiveBarChart({
|
export function InteractiveBarChart({
|
||||||
data,
|
data,
|
||||||
}: {
|
}: {
|
||||||
|
|
@ -47,7 +49,8 @@ export function InteractiveBarChart({
|
||||||
accessibilityLayer
|
accessibilityLayer
|
||||||
data={data}
|
data={data}
|
||||||
margin={{ left: 12, right: 12 }}
|
margin={{ left: 12, right: 12 }}
|
||||||
barCategoryGap="42%"
|
barGap={15}
|
||||||
|
barSize={8}
|
||||||
>
|
>
|
||||||
<CartesianGrid vertical={false} stroke="#475569" />
|
<CartesianGrid vertical={false} stroke="#475569" />
|
||||||
<XAxis
|
<XAxis
|
||||||
|
|
@ -64,14 +67,14 @@ export function InteractiveBarChart({
|
||||||
axisLine={false}
|
axisLine={false}
|
||||||
tickMargin={8}
|
tickMargin={8}
|
||||||
tick={{ fill: "#94a3b8", fontSize: 12 }}
|
tick={{ fill: "#94a3b8", fontSize: 12 }}
|
||||||
tickFormatter={(value) => `${value}%`}
|
tickFormatter={(value) => `${formatNumber(Math.round(value))}%`}
|
||||||
/>
|
/>
|
||||||
<Bar dataKey="capacity" fill={chartConfig.capacity.color} radius={[8, 8, 0, 0]}>
|
<Bar dataKey="capacity" fill={chartConfig.capacity.color} radius={[8, 8, 0, 0]}>
|
||||||
<LabelList
|
<LabelList
|
||||||
dataKey="capacity"
|
dataKey="capacity"
|
||||||
position="top"
|
position="top"
|
||||||
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
||||||
formatter={(v: number) => `${Math.round(v)}%`}
|
formatter={(v: number) => `${formatNumber(Math.round(v))}%`}
|
||||||
/>
|
/>
|
||||||
</Bar>
|
</Bar>
|
||||||
<Bar dataKey="revenue" fill={chartConfig.revenue.color} radius={[8, 8, 0, 0]}>
|
<Bar dataKey="revenue" fill={chartConfig.revenue.color} radius={[8, 8, 0, 0]}>
|
||||||
|
|
@ -79,7 +82,7 @@ export function InteractiveBarChart({
|
||||||
dataKey="revenue"
|
dataKey="revenue"
|
||||||
position="top"
|
position="top"
|
||||||
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
||||||
formatter={(v: number) => `${Math.round(v)}%`}
|
formatter={(v: number) => `${formatNumber(Math.round(v))}%`}
|
||||||
/>
|
/>
|
||||||
</Bar>
|
</Bar>
|
||||||
<Bar dataKey="cost" fill={chartConfig.cost.color} radius={[8, 8, 0, 0]}>
|
<Bar dataKey="cost" fill={chartConfig.cost.color} radius={[8, 8, 0, 0]}>
|
||||||
|
|
@ -87,7 +90,7 @@ export function InteractiveBarChart({
|
||||||
dataKey="cost"
|
dataKey="cost"
|
||||||
position="top"
|
position="top"
|
||||||
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
||||||
formatter={(v: number) => `${Math.round(v)}%`}
|
formatter={(v: number) => `${formatNumber(Math.round(v))}%`}
|
||||||
/>
|
/>
|
||||||
</Bar>
|
</Bar>
|
||||||
</BarChart>
|
</BarChart>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user