From 1dd5ea70f461383b3ffe4c4c35ff0bf69f215737 Mon Sep 17 00:00:00 2001 From: saeed0920 Date: Sun, 7 Sep 2025 03:39:21 +0330 Subject: [PATCH] delete the useless files ,also update the chart and canvas (#7) Reviewed-on: https://git.pelekan.org/Saeed0920/inogen/pulls/7 Co-authored-by: saeed0920 Co-committed-by: saeed0920 --- app/components/dashboard/d3-image-info.tsx | 290 ++++++++++-------- .../dashboard/dashboard-custom-bar-chart.tsx | 2 +- app/components/dashboard/dashboard-home.tsx | 28 +- .../dashboard/interactive-bar-chart.tsx | 15 +- 4 files changed, 179 insertions(+), 156 deletions(-) diff --git a/app/components/dashboard/d3-image-info.tsx b/app/components/dashboard/d3-image-info.tsx index f14ede0..4463bda 100644 --- a/app/components/dashboard/d3-image-info.tsx +++ b/app/components/dashboard/d3-image-info.tsx @@ -1,5 +1,4 @@ -import React, { useEffect, useRef, useState } from "react"; -import * as d3 from "d3"; +import React from "react"; import { formatNumber } from "~/lib/utils"; export type CompanyInfo = { @@ -17,141 +16,162 @@ export type D3ImageInfoProps = { height?: number; }; -export function D3ImageInfo({ companies, width = 900, height = 400 }: D3ImageInfoProps) { - const containerRef = useRef(null); - const svgRef = useRef(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]); - +const InfoBox = ({ company, style }: { company: CompanyInfo; style :any }) => { return ( -
-
- +
+
+
+
درآمد:
+
{formatNumber(company?.revenue || 0)}
+
میلیون ریال
+
+
+
هزینه:
+
{formatNumber(company?.cost || 0)}
+
میلیون ریال
+
+
+
ظرفیت:
+
{formatNumber(company?.capacity || 0)}
+
تن در سال
+
); +}; + +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 ( +
+
+ {displayCompanies.map((company, index) => { + const gp = gridPositions.find(v => v.name === company.name) || { col: (index % 5) + 1, row: Math.floor(index / 5) + 1 }; + return ( + <> +
+
+ {company.name} +
+ + {company.name} +
+ + ); + })} +
+ + +
+ ); } diff --git a/app/components/dashboard/dashboard-custom-bar-chart.tsx b/app/components/dashboard/dashboard-custom-bar-chart.tsx index fff9e2a..3ef9c0e 100644 --- a/app/components/dashboard/dashboard-custom-bar-chart.tsx +++ b/app/components/dashboard/dashboard-custom-bar-chart.tsx @@ -60,7 +60,7 @@ export function DashboardCustomBarChart({ {formatNumber(item.value)} - + {item.label}
diff --git a/app/components/dashboard/dashboard-home.tsx b/app/components/dashboard/dashboard-home.tsx index f1ef356..81d6f95 100644 --- a/app/components/dashboard/dashboard-home.tsx +++ b/app/components/dashboard/dashboard-home.tsx @@ -126,19 +126,19 @@ export function DashboardHome() { let incCapacityTotal = 0; const chartRows = rows.map((r) => { const rel = r?.related_company ?? "-"; - const preFee = Number(r?.pre_innovation_fee_sum ?? 0); - const costRed = Number(r?.innovation_cost_reduction_sum ?? 0); - const preCap = Number(r?.pre_project_production_capacity_sum ?? 0); - const incCap = Number(r?.increased_capacity_after_innovation_sum ?? 0); - const preInc = Number(r?.pre_project_income_sum ?? 0); - const incInc = Number(r?.increased_income_after_innovation_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) > 0 ? r?.innovation_cost_reduction_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) > 0 ? r?.increased_capacity_after_innovation_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) > 0 ? r?.increased_income_after_innovation_sum : 0; incCapacityTotal += incCap; const capacityPct = preCap > 0 ? (incCap / preCap) * 100 : 0; const revenuePct = preInc > 0 ? (incInc / preInc) * 100 : 0; const costPct = preFee > 0 ? (costRed / preFee) * 100 : 0; - + console.log(costRed) return { category: rel, capacity: isFinite(capacityPct) ? capacityPct : 0, @@ -475,7 +475,7 @@ export function DashboardHome() {
-

+

{formatNumber( dashboardData.topData ?.technology_innovation_based_revenue_growth || "0", @@ -487,7 +487,7 @@ export function DashboardHome() {

/
-

+

{formatNumber( Math.round( dashboardData.topData @@ -518,7 +518,7 @@ export function DashboardHome() {

-

+

{formatNumber( Math.round( parseFloat( @@ -536,7 +536,7 @@ export function DashboardHome() {

/
-

+

{formatNumber( Math.round( dashboardData.topData @@ -642,7 +642,7 @@ export function DashboardHome() {

- +
مصوب :
{formatNumber( Math.round( @@ -655,7 +655,7 @@ export function DashboardHome() { ), )}
- +
جذب شده :
{formatNumber( Math.round( @@ -700,7 +700,7 @@ export function DashboardHome() { -
+
{ diff --git a/app/components/dashboard/interactive-bar-chart.tsx b/app/components/dashboard/interactive-bar-chart.tsx index 4632cf7..505fd78 100644 --- a/app/components/dashboard/interactive-bar-chart.tsx +++ b/app/components/dashboard/interactive-bar-chart.tsx @@ -11,6 +11,7 @@ import { type ChartConfig, ChartContainer, } from "~/components/ui/chart"; +import { formatNumber } from "~/lib/utils"; export type CompanyChartDatum = { category: string; // related_company @@ -22,7 +23,7 @@ export type CompanyChartDatum = { const chartConfig = { capacity: { label: "افزایش ظرفیت", - color: "#60A5FA", // Blue-400 + color: "#69C8EA", }, revenue: { label: "افزایش درآمد", @@ -34,6 +35,7 @@ const chartConfig = { }, } satisfies ChartConfig; + export function InteractiveBarChart({ data, }: { @@ -47,7 +49,8 @@ export function InteractiveBarChart({ accessibilityLayer data={data} margin={{ left: 12, right: 12 }} - barCategoryGap="42%" + barGap={15} + barSize={8} > `${value}%`} + tickFormatter={(value) => `${formatNumber(Math.round(value))}%`} /> `${Math.round(v)}%`} + formatter={(v: number) => `${formatNumber(Math.round(v))}%`} /> @@ -79,7 +82,7 @@ export function InteractiveBarChart({ dataKey="revenue" position="top" style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }} - formatter={(v: number) => `${Math.round(v)}%`} + formatter={(v: number) => `${formatNumber(Math.round(v))}%`} /> @@ -87,7 +90,7 @@ export function InteractiveBarChart({ dataKey="cost" position="top" style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }} - formatter={(v: number) => `${Math.round(v)}%`} + formatter={(v: number) => `${formatNumber(Math.round(v))}%`} />