@@ -15,103 +15,104 @@ Preview is best-effort. Some templates may rely on Postman-specific APIs that ar
1515<summary >Visualizer HTML/script source</summary >
1616
1717```` html
18- // Visualization Script
18+ // Remarks (CODING_AGENTS visual standard)
19+ // - Device Info uses a separate top block with standardized labels
20+ // - Histogram chart remains the primary visualization
21+ // - Missing sysDescr fields render as N/A
1922const template = `
2023<style >
2124 body {
2225 font-family : Arial , sans-serif ;
23- padding : 20 px ;
24- background-color : #1e1e1e ;
25- color : #e0e0e0 ;
26+ padding : 16 px ;
27+ background-color : #0b0b0b ;
28+ color : #e8e8e8 ;
2629 }
2730 .container {
28- max-width : 1200 px ;
31+ max-width : 1280 px ;
2932 margin : 0 auto ;
3033 }
3134 .header {
32- background : linear-gradient (135deg , #4a5568 0% , #2d3748 100% );
33- color : #e0e0e0 ;
34- padding : 20px ;
35- border-radius : 8px ;
36- margin-bottom : 20px ;
37- }
38- .header h1 {
39- margin : 0 0 10px 0 ;
40- font-size : 24px ;
41- color : #e0e0e0 ;
42- }
43- .header p {
44- margin : 5px 0 ;
45- opacity : 0.9 ;
46- color : #b0b0b0 ;
47- }
48- .device-info {
49- background : #2d2d2d ;
50- padding : 20px ;
51- border-radius : 8px ;
52- margin-bottom : 20px ;
53- box-shadow : 0 2px 4px rgba (0 ,0 ,0 ,0.3 );
54- }
55- .device-info h2 {
56- margin-top : 0 ;
57- color : #e0e0e0 ;
58- border-bottom : 2px solid #4a5568 ;
59- padding-bottom : 10px ;
60- }
61- .info-grid {
35+ margin-bottom : 12px ;
6236 display : grid ;
63- grid-template-columns : repeat ( auto-fit , minmax ( 200 px , 1fr )) ;
64- gap : 15 px ;
65- margin-top : 15 px ;
37+ grid-template-columns : 1 fr auto 1fr ;
38+ align-items : center ;
39+ gap : 8 px ;
6640 }
67- .info-item {
68- padding : 10px ;
69- background : #3d3d3d ;
70- border-radius : 4px ;
41+ .header h1 {
42+ margin : 0 ;
43+ font-size : 22px ;
44+ color : #f2f2f2 ;
45+ grid-column : 2 ;
46+ text-align : center ;
7147 }
72- .info-label {
73- font-weight : bold ;
74- color : #7c9cbf ;
48+ .capture-time {
49+ grid-column : 3 ;
50+ justify-self : end ;
7551 font-size : 12px ;
76- text-transform : uppercase ;
52+ color : #d7deec ;
53+ background : rgba (255 ,255 ,255 ,0.03 );
54+ border : 1px solid rgba (255 ,255 ,255 ,0.08 );
55+ border-radius : 999px ;
56+ padding : 6px 10px ;
57+ white-space : nowrap ;
7758 }
78- .info-value {
79- color : #e0e0e0 ;
80- font-size : 16px ;
81- margin-top : 5px ;
59+ .panel {
60+ background : #151515 ;
61+ border : 1px solid #2a2a2a ;
62+ border-radius : 10px ;
63+ padding : 14px ;
64+ margin-bottom : 12px ;
8265 }
83- .chart-container {
84- background : #2d2d2d ;
85- padding : 20 px ;
86- border-radius : 8 px ;
87- margin-bottom : 20 px ;
88- box-shadow : 0 2 px 4 px rgba ( 0 , 0 , 0 , 0.3 ) ;
66+ .panel-title {
67+ margin : 0 0 10 px 0 ;
68+ font-size : 11 px ;
69+ text-transform : uppercase ;
70+ letter-spacing : 0.7 px ;
71+ color : #dbe3ff ;
8972 }
90- .chart-container h2 {
91- margin-top : 0 ;
92- color : #e0e0e0 ;
93- border-bottom : 2px solid #4a5568 ;
94- padding-bottom : 10px ;
73+ .table-wrap {
74+ overflow-x : auto ;
75+ border : 1px solid rgba (255 ,255 ,255 ,0.08 );
76+ border-radius : 10px ;
9577 }
96- .stats- table {
78+ .table {
9779 width : 100% ;
80+ min-width : 720px ;
9881 border-collapse : collapse ;
99- margin-top : 10px ;
10082 }
101- .stats-table th {
102- background : #3d3d3d ;
103- color : #e0e0e0 ;
104- padding : 10px ;
83+ .table th {
10584 text-align : left ;
106- border-bottom : 2px solid #4a5568 ;
85+ white-space : nowrap ;
86+ padding : 9px 12px ;
87+ font-size : 11px ;
88+ text-transform : uppercase ;
89+ letter-spacing : 0.45px ;
90+ color : #dbe3ff ;
91+ background : rgba (255 ,255 ,255 ,0.03 );
92+ }
93+ .table td {
94+ padding : 10px 12px ;
95+ font-size : 12px ;
96+ color : #ffffff ;
97+ white-space : nowrap ;
98+ border-top : 1px solid rgba (255 ,255 ,255 ,0.08 );
10799 }
108- .stats-table td {
109- padding : 8px 10px ;
110- border-bottom : 1px solid #3d3d3d ;
111- color : #b0b0b0 ;
100+ .mono {
101+ font-family : Consolas, " Liberation Mono" , Menlo, monospace ;
112102 }
113- .stats-table tr :hover {
114- background : #3d3d3d ;
103+ .meta-row {
104+ display : flex ;
105+ gap : 10px ;
106+ flex-wrap : wrap ;
107+ margin-top : 8px ;
108+ color : #cfd6e5 ;
109+ font-size : 12px ;
110+ }
111+ .meta-pill {
112+ background : rgba (255 ,255 ,255 ,0.03 );
113+ border : 1px solid rgba (255 ,255 ,255 ,0.08 );
114+ border-radius : 999px ;
115+ padding : 6px 10px ;
115116 }
116117 canvas {
117118 max-width : 100% ;
@@ -121,59 +122,43 @@ const template = `
121122
122123<div class =" container" >
123124 <div class =" header" >
124- <h1 >📊 Histogram Capture Analysis</h1 >
125- <p ><strong >MAC Address:</strong > {{mac_address}}</p >
126- <p ><strong >Status:</strong > {{status_message}}</p >
125+ <h1 >Histogram Capture Analysis</h1 >
126+ <div class =" capture-time" >Capture Time: {{capture_time}}</div >
127127 </div >
128128
129- {{#if device_details}}
130- <div class =" device-info" >
131- <h2 >🖥️ Device Information</h2 >
132- <div class =" info-grid" >
133- <div class =" info-item" >
134- <div class =" info-label" >Vendor</div >
135- <div class =" info-value" >{{device_details.VENDOR}}</div >
136- </div >
137- <div class =" info-item" >
138- <div class =" info-label" >Model</div >
139- <div class =" info-value" >{{device_details.MODEL}}</div >
140- </div >
141- <div class =" info-item" >
142- <div class =" info-label" >Hardware Rev</div >
143- <div class =" info-value" >{{device_details.HW_REV}}</div >
144- </div >
145- <div class =" info-item" >
146- <div class =" info-label" >Software Rev</div >
147- <div class =" info-value" >{{device_details.SW_REV}}</div >
148- </div >
129+ <div class =" panel" >
130+ <div class =" panel-title" >Device Info</div >
131+ <div class =" table-wrap" >
132+ <table class =" table" >
133+ <thead >
134+ <tr >
135+ <th >MacAddress</th >
136+ <th >Model</th >
137+ <th >Vendor</th >
138+ <th >SW Version</th >
139+ <th >HW Version</th >
140+ <th >Boot ROM</th >
141+ </tr >
142+ </thead >
143+ <tbody >
144+ <tr >
145+ <td class =" mono" >{{device_info.macAddress}}</td >
146+ <td >{{device_info.MODEL}}</td >
147+ <td >{{device_info.VENDOR}}</td >
148+ <td class =" mono" >{{device_info.SW_REV}}</td >
149+ <td class =" mono" >{{device_info.HW_REV}}</td >
150+ <td class =" mono" >{{device_info.BOOTR}}</td >
151+ </tr >
152+ </tbody >
153+ </table >
154+ </div >
155+ <div class =" meta-row" >
156+ <div class =" meta-pill" >Bins: {{bin_count}}</div >
149157 </div >
150158 </div >
151- {{/if}}
152-
153- {{#if measurement_stats}}
154- <div class =" device-info" >
155- <h2 >📈 Measurement Statistics</h2 >
156- <table class =" stats-table" >
157- <thead >
158- <tr >
159- <th >Parameter</th >
160- <th >Value</th >
161- </tr >
162- </thead >
163- <tbody >
164- {{#each measurement_stats}}
165- <tr >
166- <td >{{this.label}}</td >
167- <td >{{this.value}}</td >
168- </tr >
169- {{/each}}
170- </tbody >
171- </table >
172- </div >
173- {{/if}}
174159
175- <div class =" chart-container " >
176- <h2 >📊 Histogram Distribution</h2 >
160+ <div class =" panel " >
161+ <div class = " panel-title " > Histogram Distribution</div >
177162 <canvas id =" histogramChart" ></canvas >
178163 </div >
179164</div >
@@ -195,8 +180,8 @@ const template = `
195180 datasets: [{
196181 label: ' Hit Count' ,
197182 data: data .chart_data ,
198- backgroundColor: ' rgba(75, 192, 192 , 0.6 )' ,
199- borderColor: ' rgba(75, 192, 192, 1 )' ,
183+ backgroundColor: ' rgba(0, 194, 255 , 0.45 )' ,
184+ borderColor: ' rgba(0, 194, 255, 0.95 )' ,
200185 borderWidth: 1
201186 }]
202187 },
@@ -210,7 +195,7 @@ const template = `
210195 fontColor: ' #e0e0e0'
211196 },
212197 gridLines: {
213- color: ' #3d3d3d '
198+ color: ' rgba(255,255,255,0.08) '
214199 },
215200 scaleLabel: {
216201 display: true ,
@@ -223,7 +208,7 @@ const template = `
223208 fontColor: ' #e0e0e0'
224209 },
225210 gridLines: {
226- color: ' #3d3d3d '
211+ color: ' rgba(255,255,255,0.06) '
227212 },
228213 scaleLabel: {
229214 display: true ,
@@ -245,39 +230,50 @@ const template = `
245230
246231function constructVisualizerPayload() {
247232 const response = pm.response.json();
233+ const data = response.data || {};
234+ const firstAnalysis = (data.analysis && data.analysis[0]) || {};
235+ const pnmHeader = firstAnalysis.pnm_header || {};
236+
237+ function formatCaptureTime(raw) {
238+ if (raw === undefined || raw === null || raw === '') return 'N/A';
239+ if (typeof raw === 'number' && isFinite(raw)) {
240+ const ms = raw > 1e12 ? raw : raw * 1000;
241+ const d = new Date(ms);
242+ if (isNaN(d.getTime())) return 'N/A';
243+ return d.toISOString().slice(0, 19).replace('T', ' ') + ' UTC';
244+ }
245+ const n = Number(raw);
246+ if (!isNaN(n) && isFinite(n)) {
247+ return formatCaptureTime(n);
248+ }
249+ const d = new Date(raw);
250+ if (isNaN(d.getTime())) return String(raw);
251+ return d.toISOString().slice(0, 19).replace('T', ' ') + ' UTC';
252+ }
248253
249254 // Extract basic info
250- const macAddress = response.mac_address || 'N/A';
255+ const macAddress = firstAnalysis.mac_address || response.mac_address || 'N/A';
251256 const status = response.status;
252- const statusMessage = status === 0 ? '✅ Success' : '❌ Failed';
257+ const statusMessage = status === 0 ? 'Success' : 'Failed';
258+ const captureTime = formatCaptureTime(pnmHeader.capture_time);
253259
254260 // Extract device details
255- let deviceDetails = null;
256- if (response.data && response.data.analysis && response.data.analysis.length > 0) {
257- const analysis = response.data.analysis[0];
258- if (analysis.device_details && analysis.device_details.system_description) {
259- deviceDetails = analysis.device_details.system_description;
260- }
261- }
262-
263- // Extract measurement stats
264- let measurementStats = [];
265- if (response.data && response.data.measurement_stats && response.data.measurement_stats.length > 0) {
266- const stats = response.data.measurement_stats[0].entry;
267- measurementStats = [
268- { label: 'Histogram Enabled', value: stats.docsPnmCmDsHistEnable ? 'Yes' : 'No' },
269- { label: 'Timeout (seconds)', value: stats.docsPnmCmDsHistTimeOut },
270- { label: 'Measurement Status', value: stats.docsPnmCmDsHistMeasStatus },
271- { label: 'File Name', value: stats.docsPnmCmDsHistFileName }
272- ];
273- }
261+ const sys = ((firstAnalysis.device_details || {}).system_description) || {};
262+ const deviceInfo = {
263+ macAddress: macAddress,
264+ MODEL: (sys.MODEL && String(sys.MODEL).trim()) || 'N/A',
265+ VENDOR: (sys.VENDOR && String(sys.VENDOR).trim()) || 'N/A',
266+ SW_REV: (sys.SW_REV && String(sys.SW_REV).trim()) || 'N/A',
267+ HW_REV: (sys.HW_REV && String(sys.HW_REV).trim()) || 'N/A',
268+ BOOTR: (sys.BOOTR && String(sys.BOOTR).trim()) || 'N/A'
269+ };
274270
275271 // Extract histogram data for chart - MODIFIED TO REMOVE "Bin_" PREFIX
276272 let chartLabels = [];
277273 let chartData = [];
278274
279- if (response. data && response.data. analysis && response. data.analysis.length > 0) {
280- const analysis = response. data.analysis[0];
275+ if (data. analysis && data.analysis.length > 0) {
276+ const analysis = data.analysis[0];
281277 if (analysis.hit_counts && Array.isArray(analysis.hit_counts)) {
282278 chartData = analysis.hit_counts;
283279 // Generate labels as just the numeric index (0, 1, 2, 3, ...)
@@ -288,10 +284,11 @@ function constructVisualizerPayload() {
288284 return {
289285 mac_address: macAddress,
290286 status_message: statusMessage,
291- device_details: deviceDetails ,
292- measurement_stats: measurementStats ,
287+ capture_time: captureTime ,
288+ device_info: deviceInfo ,
293289 chart_labels: chartLabels,
294- chart_data: chartData
290+ chart_data: chartData,
291+ bin_count: chartData.length
295292 };
296293}
297294
0 commit comments