TuBrief
구독 채널
비디오
커뮤니티

كيفية تقليص حزم لوحات المعلومات المتضخمة باستخدام Recharts إلى TanStack Charts

TuBrief 편집팀
2026년 8월 12일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

العربية한국어EnglishEspañol中文हिन्दीDeutschFrançaisPortuguêsРусскийBahasa Indonesia日本語

관련 영상

تان ستارك يفعلونها مجدداً... لقد أصلحوا المخططات البيانية8:14

تان ستارك يفعلونها مجدداً... لقد أصلحوا المخططات البيانية

Better Stack

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

كيفية تقليص حزم لوحات المعلومات المتضخمة باستخدام Recharts إلى TanStack Charts

إذا دخلت صفحة لوحة معلومات وتظهر ساعة الرمل بسبب تحميل الرسوم البيانية، فالسبب بنسبة تسعين بالمائة هو مشكلة في Recharts. رؤية حجم الحزمة يتضخم بمقدار مئات الكيلوبايتات لمجرد إضافة بضع رسوم بيانية تجعل المرء يتنهد. ترتبط مكتبة Recharts ارتباطاً وثيقاً بدورة ضبط DOM في React، مما يجعل بنية واجهة المستخدم معالجة البيانات متداخلة بشكل يصعب معه استخدامها بخفة.

في مثل هذه الحالات، تعد TanStack Charts بديلاً مناسباً. فقد تم فصل منطق التجسيد (Visualization) في نواة مستقلة مبنية على قواعد الرسوم (Grammar of Graphics). بينما تستهلك Recharts عادةً أكثر من 150 كيلوبايت، فإن TanStack Charts لا تتجاوز 40 كيلوبايت تقريباً، مما يقلل من حجم الحزمة بنسبة يقارب 70%.

تكمن المشكلة في ترحيل كود الإنتاج (Production). فالتلاعب بشاشة تعمل بشكل جيد يثير القلق دائماً. ولإقناع أعضاء الفريق والانتقال بسلاسة دون أخطاء، يلزم وجود تسلسل واضح.

التخلص الآمن من كود Recharts

محاولة تغيير كل شيء دفعة واحدة تجعل من الصعب اكتشاف مصدر الأعطال. يجب اختيار مكون واحد وتفكيكه إلى 4 خطوات دقيقة:

  1. فصل المعالجة المسبقة للبيانات: نقل منطق معالجة البيانات المدمج داخل JSX الخاص بمكون Recharts إلى وظائف نقية (Pure Functions) خارجياً.
  2. ربط العلامات (Mark Mapping): نقل إعدادات المحاور والعناصر المرئية مثل الخطوط والنقاط إلى مصفوفة marks الخاصة بكائن إعلان defineChart.
  3. استبدال الأدوات المساعدة (Utilities): استبدال ResponsiveContainer و Tooltip بمقياس TanStack التلقائي وحدود @tanstack/charts/tooltip.
  4. التحفظ (Memoization): تغليف كائن تعريف الرسوم البيانية بـ useMemo وتمريره إلى مكون Chart الرئيسي.

باتباع هذا التسلسل، يمكنك تقليل الوقت المستغرق لاستبدال مكون الرسوم البيانية الأول إلى النصف.

`typescript
import React, { useMemo } from 'react';
import { defineChart, lineY, dot } from '@tanstack/charts';
import { scaleBand } from '@tanstack/charts/scales/band';
import { scaleLinear } from '@tanstack/charts/scales/linear';
import { tooltip } from '@tanstack/charts/tooltip';
import { Chart } from '@tanstack/charts/react';

interface DataRow {
date: string;
value: number;
}

export function MigratedRevenueChart({ data }: { data: DataRow[] }) {
const definition = useMemo(() => {
return defineChart({
marks: [
lineY(data, {
x: 'date',
y: 'value',
stroke: 'var(--ts-chart-1, #2563eb)',
strokeWidth: 2,
}),
dot(data, {
x: 'date',
y: 'value',
fill: 'var(--ts-chart-1, #2563eb)',
r: 4,
}),
],
x: {
scale: () => scaleBand().padding(0.2),
},
y: {
scale: scaleLinear,
nice: true,
grid: true,
},
tooltip: {
use: tooltip,
className: 'custom-tooltip',
},
});
}, [data]);

return (
<div style={{ width: '100%', height: 300 }}>


);
}

`

تجنب إعادة تصيير JavaScript عند التعامل مع الوضع الليلي (Dark Mode)

إعادة رسم مكون الرسم البياني بالكامل في كل مرة يتم فيها تبديل الوضع الليلي يعد أمراً مزعجاً. تدعم TanStack Charts خصائص CSS المخصصة و currentColor مباشرةً بدلاً من قيم الألوان المكتوبة صراحةً.

بدلاً من إدارة ألوان الرسم البياني كحالة JavaScript، قم بإدخالها عبر متغيرات CSS. ما عليك سوى جعل لوحة الألوان الافتراضية للرسم البياني تشير إلى --ts-chart-1 حتى --ts-chart-6.

  1. قم بتعريف متغيرات الرسم البياني مسبقاً في جذر CSS و [data-theme='dark'].
  2. أدخل سلاسل نصية بالشكل var(--ts-chart-1) في خيارات stroke أو fill الخاصة بـ defineChart.
  3. قم بإدارة أنماط تلميح الأدوات (Tooltip) أيضاً كفئات CSS ومعالجة لون الخلفية كمتغير.

من خلال إعدادها بهذه الطريقة، لن تحتاج إلى لمس ملفات TSX عندما يطلب المصمم تغيير ألوان الرسوم البيانية؛ يكفي تعديل CSS فقط وينتهي الأمر.

`css
:root {
--bg-chart-card: #ffffff;
--text-chart-main: #172033;
--border-chart-grid: #e2e8f0;
--ts-chart-1: #2563eb;
--ts-chart-2: #f97316;
}

[data-theme='dark'] {
--bg-chart-card: #0f172a;
--text-chart-main: #f8fafc;
--border-chart-grid: #334155;
--ts-chart-1: #60a5fa;
--ts-chart-2: #fb923c;
}

.custom-tooltip {
background-color: var(--bg-chart-card);
color: var(--text-chart-main);
border: 1px solid var(--border-chart-grid);
padding: 8px 12px;
border-radius: 6px;
}

`

ضمان عدم تعطل التطبيق حتى عند إدخال 100 ألف نقطة بيانات

عند تصيير 100 ألف نقطة باستخدام SVG، يتم إنشاء 100 ألف عقدة DOM، مما يمنع خيط المتصفح (Thread) من التحمل، وتظهر التقطيعات بوضوح للعين.

الحل يكمن في دمج أمرين: التحول إلى عارض Canvas للقضاء على تكلفة إنشاء DOM، وضغط البيانات المكتظة بلا مبرر بما يتجاوز عرض بكسل الشاشة باستخدام خوارزمية LTTB (Largest Triangle Three Buckets). تحافظ LTTB على الخصائص البارزة للبيانات (القيم العظمى والدنيا) مع تقليل عدد النقاط.

`typescript
export function lttbDownsample(
data: T[],
xAccessor: (d: T) => number,
yAccessor: (d: T) => number,
threshold: number
): T[] {
const dataLength = data.length;
if (threshold >= dataLength || threshold === 0) return data;

const sampled: T[] = [];
let sampledIndex = 0;
const bucketSize = (dataLength - 2) / (threshold - 2);

sampled[sampledIndex++] = data[0];

for (let i = 0; i < threshold - 2; i++) {
let avgX = 0;
let avgY = 0;
const avgRangeStart = Math.floor((i + 1) * bucketSize) + 1;
const avgRangeEnd = Math.floor((i + 2) * bucketSize) + 1;
const currentAvgRangeEnd = avgRangeEnd < dataLength ? avgRangeEnd : dataLength;

for (let j = avgRangeStart; j < currentAvgRangeEnd; j++) {
  avgX += xAccessor(data[j]);
  avgY += yAccessor(data[j]);
}
avgX /= (currentAvgRangeEnd - avgRangeStart);
avgY /= (currentAvgRangeEnd - avgRangeStart);

const rangeOffs = Math.floor((i + 0) * bucketSize) + 1;
const rangeTo = Math.floor((i + 1) * bucketSize) + 1;
const pointAX = xAccessor(sampled[sampledIndex - 1]);
const pointAY = yAccessor(sampled[sampledIndex - 1]);

let maxArea = -1;
let maxAreaPointIndex = rangeOffs;

for (let j = rangeOffs; j < rangeTo; j++) {
  const area = Math.abs(
    (pointAX - avgX) * (yAccessor(data[j]) - pointAY) -
    (pointAX - xAccessor(data[j])) * (avgY - pointAY)
  ) * 0.5;

  if (area > maxArea) {
    maxArea = area;
    maxAreaPointIndex = j;
  }
}
sampled[sampledIndex++] = data[maxAreaPointIndex];

}

sampled[sampledIndex++] = data[dataLength - 1];
return sampled;
}

`

عند التعاملกับ السلاسل الزمنية الكبيرة، استخدم LTTB لتقليص حجم البيانات إلى حوالي 1000 نقطة. بعد ذلك، قم بتفعيل خيار spatialIndex: true لتقليل تعقيد اكتشاف مؤشر الماوس. وأخيراً، أضف عارض Canvas من حزمة @tanstack/charts/react/canvas لتحقيق معدل 60 إطاراً في الثانية (60fps).

كيفية تكليف Cursor أو Copilot بكتابة كود الرسوم البيانية

التنسيقات التي تحتوي على وسوم JSX متداخلة بعمق مثل Recharts غالباً ما تتسبب في هلوسة المساعد الذكي، حيث يولد خصائص غريبة أو يفشل في إغلاق الوسوم.

أما المكتبات التي تعتمد على صيغة إعلان الكائنات مثل TanStack Charts، فيمكنها إنتاج كود نظيف من قِبل الذكاء الاصطناعي شريطة تزويده بمخطط الأنواع (Type Schema) بشكل صحيح. قم بتعريف نوع مخطط مثل أدناه في مشروعك وضعه في توجيهات الذكاء الاصطناعي أو ملف القواعد (.cursorrules).

`typescript
export type ScaleType = 'linear' | 'band' | 'utc' | 'point';
export type MarkType = 'lineY' | 'barY' | 'dot' | 'areaY';

export interface AIScaleConfig {
type: ScaleType;
nice?: boolean;
grid?: boolean;
padding?: number;
}

export interface AIMarkConfig {
type: MarkType;
xKey: string;
yKey: string;
color?: string;
strokeWidth?: number;
}

export interface AIChartGenerationSchema {
data: Record<string, unknown>[];
scales: {
x: AIScaleConfig;
y: AIScaleConfig;
};
marks: AIMarkConfig[];
tooltip?: {
enabled: boolean;
className?: string;
};
}

`

إذا قمت بكتابة قواعد الاستيراد من المسارات الفرعية الدقيقة مثل @tanstack/charts/scales/linear وقواعد استخدام useMemo في موجه (Prompt) الذكاء الاصطناعي، يمكنك استخدام الكود الذي يخرجه الذكاء الاصطناعي مباشرة دون أي تعديلات.