Data Visualization and Charts
Relevant source files
The following files were used as context for generating this wiki page:
The DSS-SPK_KAJEK application employs a rich suite of data visualization components to interpret and present the results of the TOPSIS analysis. These charts provide an intuitive way for users to understand vendor rankings, compare alternatives across multiple criteria, and analyze historical trends. The primary technologies used for charting are Recharts for 2D interactive charts and Three.js for 3D visualizations.
Visualizations are primarily centralized within the AnalysisView, which acts as a control hub for generating and displaying charts based on user-defined weights. Other components like HistoryView and DashboardView also use specialized charts to display specific data points.
Sources: SUMMARY.md, frontend/src/components/AnalysisView.tsx
Charting Architecture
The application's charting architecture is component-based, with AnalysisView serving as the primary container for most visualizations. It manages the state for calculation results and passes the relevant data down to child chart components.
The diagram below illustrates the relationship between the main view and its charting components.
Core Chart Components
The system utilizes several distinct React components to render different types of visualizations.
| Component | Library | Purpose | Source File |
|---|---|---|---|
BarChart | Recharts | Displays the top-ranked vendors based on their TOPSIS score. | frontend/src/components/AnalysisView.tsx |
RadarChart | Recharts | Compares up to 3 selected vendors across normalized criteria values. | frontend/src/components/AnalysisView.tsx |
LineChart | Recharts | Used for sensitivity analysis, showing how vendor scores change as a key weight is adjusted. | frontend/src/components/AnalysisView.tsx |
Chart3D | Three.js | Provides an interactive 3D bar chart visualization of the top 10 vendors. | frontend/src/components/Chart3D.tsx |
HistoryTrendChart | Recharts | Renders an area chart showing the trend of the top score over time from saved calculations. | frontend/src/components/HistoryTrendChart.tsx |
LevelBadge | - | A micro-visualization to represent a vendor's level for a specific criterion. | frontend/src/components/DashboardView.tsx |
MorphingChart | Framer Motion | A conceptual component demonstrating animated transitions between chart types. | frontend/src/components/MorphingChart.tsx |
Sources: frontend/src/components/AnalysisView.tsx, frontend/src/components/Chart3D.tsx, frontend/src/components/HistoryTrendChart.tsx, frontend/src/components/DashboardView.tsx, frontend/src/components/MorphingChart.tsx
2D Charts (Recharts)
2D charts are built using the Recharts library and are primarily located within the AnalysisView component.
Bar Chart (Ranking)
A vertical bar chart is used to display the top 5 vendors and their final TOPSIS scores.
- Layout: Vertical, with vendor names on the Y-axis and scores on the X-axis.
- Styling: Features a custom gradient fill (
barGradient) and a custom tooltip for displaying details on hover. - Animation: Bars are animated on initial render with a duration of 1500ms.
Sources: frontend/src/components/AnalysisView.tsx:392-416
Radar Chart (Comparison)
The radar chart allows for a multi-criteria comparison of 2 to 3 selected vendors.
- Data Normalization: Before being passed to the chart, vendor criteria values are normalized to a 0-100 scale to ensure fair comparison. The
getRadarDatafunction handles this logic. For cost criteria like 'Harga' (Price), the value is inverted. - Selection: Users can select up to 3 vendors from the results list to compare. If no vendors are selected, a placeholder message is displayed.
- Components: Uses
RadarChart,PolarGrid,PolarAngleAxis,PolarRadiusAxis, andRadarcomponents from Recharts.
The following diagram shows the data flow for generating the radar chart.
Line Chart (Sensitivity Analysis)
A line chart is available to perform a sensitivity analysis, demonstrating how vendor scores are affected by changes in a specific criterion's weight.
- Functionality: The
runSensitivityAnalysisfunction simulates TOPSIS calculations by varying the CPU weight from 0.1 to 0.5 and adjusting other weights proportionally. - Display: The chart plots the scores of the top 5 vendors against the changing CPU weight.
- Interaction: The chart can be toggled on and off by the user.
Sources: frontend/src/components/AnalysisView.tsx:61-80, frontend/src/components/AnalysisView.tsx:478-515
3D Visualization (Three.js)
The application offers a 3D chart mode, which renders an interactive bar chart using Three.js. This is encapsulated in the Chart3D component.
Chart3D Component
This component is responsible for setting up and rendering a complete Three.js scene.
Props:
| Prop | Type | Description |
|---|---|---|
data | Array | An array of vendor data, including score, for the top 10 vendors. |
width | number | The width of the canvas. Defaults to 800. |
height | number | The height of the canvas. Defaults to 600. |
Sources: frontend/src/components/Chart3D.tsx:4-15
Rendering Logic:
The rendering process follows standard Three.js patterns within a useEffect hook.
- Scene Setup: A
THREE.Sceneis created with a dark background (0x0f172a). - Camera: A
PerspectiveCamerais positioned to look at the center of the scene. - Lighting: The scene is lit by an
AmbientLightand aDirectionalLightto create shadows. - Helpers: A
GridHelperandAxesHelperare added for spatial reference. - Data Mapping:
- The component iterates through the
dataprop. - For each vendor, a
THREE.BoxGeometryis created. The height of the box is proportional to the vendor'sscore. - The bar is animated to scale up from 0 on the Y-axis.
- A
THREE.Spritewith aCanvasTextureis created to display the vendor's name and score as a label above the bar.
- The component iterates through the
- Interaction: A
mousemoveevent listener allows the user to rotate the camera around the scene by moving the mouse. - Animation Loop:
requestAnimationFrameis used to create a render loop that updates the camera position and re-renders the scene.
Sources: frontend/src/components/Chart3D.tsx:21-158
The following snippet shows how each bar is created and animated.
// frontend/src/components/Chart3D.tsx:77-101
data.forEach((item, index) => {
// Bar height based on score
const height = (item.score / maxScore) * 8;
// Bar geometry
const geometry = new THREE.BoxGeometry(0.8, height, 0.8);
const material = new THREE.MeshLambertMaterial({
color: colors[index % colors.length],
transparent: true,
opacity: 0.8
});
const bar = new THREE.Mesh(geometry, material);
bar.position.set(
(index - data.length / 2) * 2,
height / 2,
0
);
bar.castShadow = true;
bar.receiveShadow = true;
// Animation
bar.scale.y = 0;
const targetScale = 1;
const animateBar = () => {
if (bar.scale.y < targetScale) {
bar.scale.y += 0.02;
requestAnimationFrame(animateBar);
}
};
setTimeout(() => animateBar(), index * 100);
scene.add(bar);
Sources: frontend/src/components/Chart3D.tsx:77-101
History Trend Chart
The HistoryTrendChart component is used to visualize the trend of the highest-scoring vendor over time, based on saved calculation history.
- Chart Type: It uses an
AreaChartfrom Recharts to show thetop_scoreprogression. - Data: It accepts an array of
HistoryItemobjects, each containing atimestampandtop_score. - Tooltip: A custom tooltip is implemented to show the full date, top vendor name, and exact score on hover.
- Styling: The area under the line is filled with a
linearGradientfor better visual appeal.
Data Structure:
interface HistoryItem {
id: number;
timestamp: string;
top_score: number;
top_vendor: string;
}
Sources: frontend/src/components/HistoryTrendChart.tsx:10-15
Micro-Visualizations
LevelBadge
The DashboardView contains a simple but effective micro-visualization component, LevelBadge, to represent the discrete levels (1-5) for each criterion.
- Functionality: It displays the level number (e.g., "Lvl 3") and a series of 5 small bars, with a number of them filled in to correspond to the level.
- Purpose: Provides a quick, at-a-glance visual representation of a vendor's rating for a specific criterion directly within a data table.