Replace single-dimension Pareto dropdown with 6 simultaneous Pareto charts (不良原因, PACKAGE, TYPE, WORKFLOW, 站點, 機台) in a responsive 3-column grid. Clicking items in one Pareto cross-filters the other 5 (exclude-self logic), and the detail table applies all dimension selections with AND logic. Backend: - Add batch-pareto endpoint (cache-only, no Oracle queries) - Add _apply_cross_filter() with exclude-self pattern - Extend view/export endpoints for multi-dimension sel_* params Frontend: - New ParetoGrid.vue wrapping 6 ParetoSection instances - Simplify ParetoSection: remove dimension dropdown, keep TOP20 toggle - Replace single-dimension state with paretoSelections reactive object - Adaptive x-axis labels (font size, rotation, hideOverlap) for compact grid - Responsive grid: 3-col desktop, 2-col tablet, 1-col mobile Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.2 KiB
5.2 KiB
MODIFIED Requirements
Requirement: Reject History page SHALL provide reason Pareto analysis
The page SHALL display 6 Pareto charts simultaneously (不良原因, PACKAGE, TYPE, WORKFLOW, 站點, 機台) in a 3-column grid layout with cross-filter linkage, replacing the single-dimension dropdown switcher.
Scenario: Multi-Pareto grid layout
- WHEN Pareto data is loaded
- THEN 6 Pareto charts SHALL be rendered simultaneously in a 3-column grid (3×2)
- THEN each chart SHALL display one dimension: 不良原因, PACKAGE, TYPE, WORKFLOW, 站點, 機台
- THEN there SHALL be no dimension dropdown selector
Scenario: Pareto rendering and ordering
- WHEN Pareto data is loaded
- THEN items in each Pareto SHALL be sorted by selected metric descending
- THEN each Pareto SHALL show a cumulative percentage line
Scenario: Pareto 80% filter is managed in supplementary filters
- WHEN the page first loads Pareto
- THEN supplementary filters SHALL include "Pareto 僅顯示累計前 80%" control
- THEN the control SHALL default to enabled
- THEN the 80% filter SHALL apply uniformly to all 6 Pareto charts
Scenario: Cross-filter linkage between Pareto charts
- WHEN user clicks an item in one Pareto chart (e.g., selects reason "A")
- THEN the other 5 Pareto charts SHALL recalculate with the selection applied as a filter
- THEN the clicked Pareto chart itself SHALL NOT be filtered by its own selections
- THEN the detail table below SHALL apply ALL selections from ALL dimensions
Scenario: Pareto click filtering supports multi-select
- WHEN user clicks Pareto bars or table rows in any dimension
- THEN clicked items SHALL become active selected chips
- THEN multiple selected items SHALL be supported within each dimension
- THEN multiple dimensions SHALL support simultaneous selections
Scenario: Re-click clears selected item only
- WHEN user clicks an already selected Pareto item
- THEN only that item SHALL be removed from selection
- THEN remaining selected items across all dimensions SHALL stay active
- THEN all Pareto charts SHALL recalculate to reflect the updated selections
Scenario: Filter chips display all dimension selections
- WHEN items are selected across multiple Pareto dimensions
- THEN selected items SHALL be displayed as chips grouped by dimension label
- THEN each chip SHALL show the dimension label and selected value (e.g., "TYPE: X")
- THEN clicking a chip's remove button SHALL deselect that item and trigger recalculation
Scenario: Responsive grid layout
- WHEN viewport is desktop width (>1200px)
- THEN Pareto charts SHALL render in a 3-column grid
- WHEN viewport is medium width (768px–1200px)
- THEN Pareto charts SHALL render in a 2-column grid
- WHEN viewport is below 768px
- THEN Pareto charts SHALL stack in a single column
Scenario: TOP20/ALL display scope control
- WHEN Pareto grid is displayed
- THEN supplementary filters SHALL include a global "只顯示 TOP 20" toggle
- THEN when enabled, applicable dimensions (TYPE, WORKFLOW, 機台) SHALL truncate to top 20 items
- THEN the toggle SHALL apply uniformly to all applicable Pareto charts (not per-chart selectors)
- THEN dimensions not in the applicable set (不良原因, PACKAGE, 站點) SHALL be unaffected by this toggle
MODIFIED Requirements
Requirement: Reject History page SHALL be structured as modular sub-components
The page template SHALL delegate sections to focused sub-components, following the hold-history architecture pattern.
Scenario: Component decomposition
- WHEN the page source is examined
- THEN the filter panel SHALL be a separate
FilterPanel.vuecomponent - THEN the KPI summary cards SHALL be a separate
SummaryCards.vuecomponent - THEN the trend chart SHALL be a separate
TrendChart.vuecomponent - THEN the pareto grid SHALL be a separate
ParetoGrid.vuecomponent containing 6ParetoSection.vueinstances - THEN each individual pareto chart+table SHALL be a
ParetoSection.vuecomponent - THEN the detail table with pagination SHALL be a separate
DetailTable.vuecomponent
Scenario: App.vue acts as orchestrator
- WHEN the page runs
- THEN
App.vueSHALL hold all reactive state and API logic - THEN sub-components SHALL receive data via props and communicate via events
Requirement: Reject History page SHALL support CSV export from current filter context
The page SHALL allow users to export records using the exact active filters.
Scenario: Export with all active filters
- WHEN user clicks "匯出 CSV"
- THEN export request SHALL include current primary filters, supplementary filters, trend-date filters, metric filters, and all Pareto-selected items from all 6 dimensions
- THEN downloaded file SHALL contain exactly the same rows currently represented by the detail list filter context
Scenario: Export remains UTF-8 Excel compatible
- WHEN CSV export is downloaded
- THEN the file SHALL be encoded in UTF-8 with BOM
- THEN Chinese headers and values SHALL render correctly in common spreadsheet tools