Skip to main content

Overview

The Product Distribution Dashboard provides an interactive interface for visualizing and analyzing product shipments between warehouses and stores. Built with Angular and Leaflet, it offers real-time insights into distribution patterns, metrics, and assignments.

Dashboard Components

The dashboard consists of four main components working together:

Filters Component

Allows users to filter data by warehouse, store, or product:
export interface DashboardFilters {
  warehouseId: string | null;
  storeId: string | null;
  productId: string | null;
}
Features:
  • Dropdown selectors for warehouses, stores, and products
  • Multi-level filtering (combine filters for detailed analysis)
  • Real-time data updates on filter changes
  • Clear filter option to reset view

Interactive Map Component

Leaflet-based map visualization showing distribution routes:
private initMap(): void {
  this.map = this.L.map('map', {
    zoomControl: false,
    attributionControl: false,
    maxBounds: [
      [-90, -180],
      [90, 180],
    ],
    minZoom: 2,
    maxZoom: 19,
    maxBoundsViscosity: 1,
  }).setView([40, 0], 2);

  this.L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
    attribution: '&copy; <a href="https://carto.com/">CARTO</a>',
    subdomains: 'abcd',
  }).addTo(this.map);
}
Map Features:
  • Store Markers: Gray circular markers representing retail locations
  • Warehouse Markers: Black circular markers representing distribution centers
  • Marker Clustering: Automatically groups nearby markers at lower zoom levels
  • Tooltips: Hover to see location IDs
  • Polylines: Purple lines connecting warehouses to stores
  • Direction Arrows: Indicate flow from warehouse to store
  • Interactive Highlighting: Routes highlight on hover
  • Route Popups: Click to see detailed shipment information
DashboardMapComponent:65-78
this.warehouseMarkers = this.L.markerClusterGroup({
  removeOutsideVisibleBounds: false,
  iconCreateFunction: (cluster: L.MarkerCluster) => {
    const childCount = cluster.getChildCount();
    return this.L.divIcon({
      html: `<div><span>${childCount}</span></div>`,
      className: 'marker-cluster marker-cluster-warehouse',
      iconSize: new this.L.Point(40, 40),
    });
  },
  polygonOptions: {
    color: '#111',
  },
}).addTo(this.map);
Marker clustering groups nearby locations and displays count badges for better performance with large datasets.

Table Component

Displays stock assignments in tabular format with sorting and pagination capabilities. Provides detailed view of all shipments with columns for:
  • Warehouse ID
  • Store ID
  • Product ID
  • Size
  • Quantity
  • Distance (km)

Metrics Components

Global Metrics - High-level overview displayed at the top:
forkJoin({
  warehouses: this.warehouseService.getAll(),
  stores: this.storeService.getAll(),
  products: this.productService.getAll(),
  globalMetrics: this.metricsService.getGlobalMetrics(),
})
Shows:
  • Total shipments
  • Fulfilled units
  • Unfulfilled units
  • Average distance
Detailed Metrics - Comprehensive analytics available in the Metrics tab (see Metrics documentation).

Visualization Features

Route Visualization

Routes are drawn as polylines with decorative arrows:
private createRouteLineGroup(
  from: [number, number],
  to: [number, number],
  group: StockAssignment[],
  fromId: string,
  toId: string
): L.Polyline {
  const baseStyle = { color: '#673ab7', weight: 2, opacity: 0.13 };
  const highlightStyle = { color: '#311b92', weight: 4, opacity: 0.8 };
  const polyline = this.L.polyline([from, to], baseStyle).bindPopup(
    this.getPopupContent(group, fromId, toId)
  );

  let decorator = this.createArrowDecoratorGroup(
    polyline,
    group,
    baseStyle.opacity,
    fromId,
    toId
  );
  decorator.addTo(this.map);

  // ... hover and popup interaction logic
  
  return polyline;
}
Visual Styling:
  • Base: Semi-transparent purple (#673ab7, opacity 0.13)
  • Highlighted: Dark purple (#311b92, opacity 0.8)
  • Arrow decorators at 50% point along route
  • Dynamic styling on hover and popup open

Route Popups

Click any route to see detailed shipment information:
private getPopupContent(group: StockAssignment[], fromId: string, toId: string): string {
  return `
  <div style="max-width: 320px; max-height: 100px; overflow-y: auto;">
    <b>Assignments</b> ${fromId}${toId}<br>
    <table style='font-size:0.95em;'>
      <thead style="position: sticky; top: 0; background: white; z-index: 2;">
        <tr><th>Product</th><th>Size</th><th>Quantity</th></tr>
      </thead>
      <tbody>
        ${group
          .map(
            a => `
          <tr>
            <td>${a.productId}</td>
            <td>${a.size}</td>
            <td>${a.quantity}</td>
          </tr>
        `
          )
          .join('')}
      </tbody>
    </table>
  </div>
  `;
}
Popups display all products shipped along that route in a scrollable table.

User Workflows

View Overall Distribution

1

Load Dashboard

Dashboard loads with all warehouses, stores, and assignments visible
2

Review Global Metrics

Check the metrics cards at the top for high-level statistics
3

Explore Map

Pan and zoom the map to explore different regions
4

Inspect Routes

Click on routes to see detailed shipment information

Analyze Specific Warehouse

1

Select Warehouse

Use the warehouse filter dropdown to select a specific warehouse
2

View Filtered Routes

Map updates to show only routes from selected warehouse
3

Check Metrics Tab

Switch to Metrics tab to see detailed analytics for this warehouse
4

Review Table

Switch to Table tab to see all assignments in sortable format

Track Product Distribution

1

Filter by Product

Select a product from the product filter dropdown
2

View Distribution Pattern

See which warehouses are shipping this product and to which stores
3

Analyze Coverage

Identify geographic patterns and coverage gaps
4

Check Fulfillment

View metrics tab to see fulfillment rate for this product

Investigate Store Supply

1

Select Store

Choose a store from the store filter dropdown
2

View Incoming Shipments

Map shows all warehouses shipping to this store
3

Review Product Mix

Check table tab to see all products being delivered
4

Assess Efficiency

View metrics to see average distance and capacity utilization

Data Filtering and Selection

Filters can be combined for granular analysis:
onFiltersChange(newFilters: DashboardFilters) {
  this.filters = newFilters;
  this.loadAssignments(this.filters);

  if (this.activeTab === 'metrics') {
    this.loadDetailedMetrics();
  }
}
Filter Combinations:
WarehouseStoreProductResult
--All shipments from specific warehouse
--All shipments to specific store
--All shipments of specific product
-Shipments from warehouse to store
-Specific product from specific warehouse
-Specific product to specific store
Specific product from warehouse to store

Tabs Navigation

The dashboard provides three view modes:
Interactive geographic visualization with routes and markers. Best for understanding spatial distribution patterns.
onTabChange(tab: DashboardTab) {
  this.activeTab = tab;

  if (tab === 'metrics') {
    this.loadDetailedMetrics();
  }
}

Performance Optimizations

  • Marker Clustering: Reduces rendering load with many locations
  • Lazy Loading: Metrics load only when tab is activated
  • Route Grouping: Multiple assignments on same route are grouped
  • Responsive Map: Auto-adjusts on window resize
  • Filtered Rendering: Only displays relevant data based on filters

Next Steps

Distribution Algorithm

Understand the logic behind warehouse selection

Metrics

Learn about available metrics and analytics

Build docs developers (and LLMs) love