@@ -119,6 +119,60 @@ func getHtmlReportBegin() string {
119119 .sidebar .togglebtn:hover {
120120 color: #666;
121121 }
122+ .field-description {
123+ position: relative;
124+ display: inline-block;
125+ margin-left: 5px;
126+ cursor: help;
127+ }
128+ .field-description .tooltip-icon {
129+ color: #fff;
130+ font-size: 12px;
131+ border: 1px solid #2196F3;
132+ border-radius: 50%;
133+ width: 16px;
134+ height: 16px;
135+ text-align: center;
136+ line-height: 14px;
137+ background-color: #2196F3;
138+ transition: background-color 0.2s, border-color 0.2s;
139+ }
140+ .field-description:hover .tooltip-icon {
141+ background-color: #1976D2;
142+ border-color: #1976D2;
143+ }
144+ .field-description .tooltip-text {
145+ visibility: hidden;
146+ width: 250px;
147+ background-color: #333;
148+ color: #fff;
149+ text-align: left;
150+ border-radius: 6px;
151+ padding: 8px;
152+ position: absolute;
153+ z-index: 1000;
154+ bottom: 125%;
155+ left: 50%;
156+ margin-left: -125px;
157+ opacity: 0;
158+ transition: opacity 0.3s;
159+ font-size: 12px;
160+ box-shadow: 0px 0px 6px rgba(0,0,0,0.2);
161+ }
162+ .field-description .tooltip-text::after {
163+ content: "";
164+ position: absolute;
165+ top: 100%;
166+ left: 50%;
167+ margin-left: -5px;
168+ border-width: 5px;
169+ border-style: solid;
170+ border-color: #333 transparent transparent transparent;
171+ }
172+ .field-description:hover .tooltip-text {
173+ visibility: visible;
174+ opacity: 1;
175+ }
122176 </style>
123177 ` )
124178 sb .WriteString ("</head>\n " )
@@ -448,14 +502,31 @@ type chartTemplateStruct struct {
448502 SuggestedMax string
449503}
450504
505+ // CreateFieldNameWithDescription creates HTML for a field name with optional description tooltip
506+ func CreateFieldNameWithDescription (fieldName , description string ) string {
507+ if description == "" {
508+ return htmltemplate .HTMLEscapeString (fieldName )
509+ }
510+ return htmltemplate .HTMLEscapeString (fieldName ) + `<span class="field-description"><span class="tooltip-icon">?</span><span class="tooltip-text">` + htmltemplate .HTMLEscapeString (description ) + `</span></span>`
511+ }
512+
451513func renderHTMLTable (tableHeaders []string , tableValues [][]string , class string , valuesStyle [][]string ) string {
514+ return renderHTMLTableWithDescriptions (tableHeaders , nil , tableValues , class , valuesStyle )
515+ }
516+
517+ // renderHTMLTableWithDescriptions renders an HTML table with optional header descriptions
518+ func renderHTMLTableWithDescriptions (tableHeaders []string , headerDescriptions []string , tableValues [][]string , class string , valuesStyle [][]string ) string {
452519 var sb strings.Builder
453520 sb .WriteString (`<table class="` + class + `">` )
454521 if len (tableHeaders ) > 0 {
455522 sb .WriteString (`<thead>` )
456523 sb .WriteString (`<tr>` )
457- for _ , label := range tableHeaders {
458- sb .WriteString (`<th>` + label + `</th>` )
524+ for i , label := range tableHeaders {
525+ var description string
526+ if headerDescriptions != nil && i < len (headerDescriptions ) {
527+ description = headerDescriptions [i ]
528+ }
529+ sb .WriteString (`<th>` + CreateFieldNameWithDescription (label , description ) + `</th>` )
459530 }
460531 sb .WriteString (`</tr>` )
461532 sb .WriteString (`</thead>` )
@@ -480,8 +551,10 @@ func renderHTMLTable(tableHeaders []string, tableValues [][]string, class string
480551func DefaultHTMLTableRendererFunc (tableValues TableValues ) string {
481552 if tableValues .HasRows { // print the field names as column headings across the top of the table
482553 headers := []string {}
554+ headerDescriptions := []string {}
483555 for _ , field := range tableValues .Fields {
484556 headers = append (headers , field .Name )
557+ headerDescriptions = append (headerDescriptions , field .Description )
485558 }
486559 values := [][]string {}
487560 for row := range tableValues .Fields [0 ].Values {
@@ -491,13 +564,13 @@ func DefaultHTMLTableRendererFunc(tableValues TableValues) string {
491564 }
492565 values = append (values , rowValues )
493566 }
494- return renderHTMLTable (headers , values , "pure-table pure-table-striped" , [][]string {})
567+ return renderHTMLTableWithDescriptions (headers , headerDescriptions , values , "pure-table pure-table-striped" , [][]string {})
495568 } else { // print the field name followed by its value
496569 values := [][]string {}
497570 var tableValueStyles [][]string
498571 for _ , field := range tableValues .Fields {
499572 rowValues := []string {}
500- rowValues = append (rowValues , field .Name )
573+ rowValues = append (rowValues , CreateFieldNameWithDescription ( field .Name , field . Description ) )
501574 rowValues = append (rowValues , htmltemplate .HTMLEscapeString (field .Values [0 ]))
502575 values = append (values , rowValues )
503576 tableValueStyles = append (tableValueStyles , []string {"font-weight:bold" })
@@ -513,7 +586,7 @@ func RenderMultiTargetTableValuesAsHTML(tableValues []TableValues, targetNames [
513586 var tableValueStyles [][]string
514587 for fieldIndex , field := range tableValues [0 ].Fields {
515588 rowValues := []string {}
516- rowValues = append (rowValues , field .Name )
589+ rowValues = append (rowValues , CreateFieldNameWithDescription ( field .Name , field . Description ) )
517590 for _ , targetTableValues := range tableValues {
518591 if len (targetTableValues .Fields ) > fieldIndex && len (targetTableValues .Fields [fieldIndex ].Values ) > 0 {
519592 rowValues = append (rowValues , htmltemplate .HTMLEscapeString (targetTableValues .Fields [fieldIndex ].Values [0 ]))
@@ -731,7 +804,7 @@ func renderFrequencyTable(tableValues TableValues) (out string) {
731804 headers = append (headers , fmt .Sprintf ("%d" , i + 1 ))
732805 }
733806 for _ , field := range tableValues .Fields [1 :] {
734- row := append ([]string {field .Name }, field .Values ... )
807+ row := append ([]string {CreateFieldNameWithDescription ( field .Name , field . Description ) }, field .Values ... )
735808 rows = append (rows , row )
736809 valuesStyles = append (valuesStyles , []string {"font-weight:bold" })
737810 }
0 commit comments