808b145f396d7d8af6ff393e1eda815ec318ae66
hiram
  Wed Jul 15 11:31:35 2020 -0700
in place of histogram table show actual values when number of data points < 25 refs #25885

diff --git src/hg/hgc/wiggleClick.c src/hg/hgc/wiggleClick.c
index 423f322..18e5157 100644
--- src/hg/hgc/wiggleClick.c
+++ src/hg/hgc/wiggleClick.c
@@ -122,48 +122,94 @@
     hRange = hMax - hMin;
 
     /*	convert the ascii data listings to one giant float array 	*/
     valuesArray = wds->asciiToDataArray(wds, valuesMatched, &valueCount);
 
     /* let's see if we really want to use the range from the track type
      *	line, or the actual range in this data.  If there is a good
      *	actual range in the data, use that instead
      */
     if (hRange > 0.0) 
     	{
 	if (wds->stats->dataRange != 0)
 	    hRange = 0.0;
 	}
 
+    if (valuesMatched < 25)
+	{
+	struct wigAsciiData *asciiData = NULL;
+        unsigned long long valuesDone = 0;
+	double worstCaseResolution = 0.0;
+
+	struct dyString *tableData = dyStringNew(256);
+	for (asciiData = wds->ascii; asciiData && (valuesDone < valuesMatched);
+	    asciiData = asciiData->next)
+	    {
+	    if (asciiData->count)
+		{
+		double resolution = asciiData->dataRange / (MAX_WIG_VALUE+1);
+		if (resolution > worstCaseResolution)
+		    worstCaseResolution = resolution;
+		struct asciiDatum *data = asciiData->data;
+		unsigned i = 0;
+		for (;(i < asciiData->count)&&(valuesDone < valuesMatched); ++i)
+		    {
+		    dyStringPrintf(tableData, "<tr>");
+		    dyStringPrintf(tableData, "<td>%s</td>", asciiData->chrom);
+		    dyStringPrintf(tableData, "<td>%d</td>", data->chromStart);
+		    dyStringPrintf(tableData, "<td>%d</td>", data->chromStart+asciiData->span);
+		    dyStringPrintf(tableData, "<td align=right>%.3f</td>", data->value);
+		    dyStringPrintf(tableData, "</tr>\n");
+		    ++data;
+		    ++valuesDone;
+		    }
+		}
+	    }
+        printf("<table class='stdTbl'>\n");
+        printf("<thead>\n");
+	printf("<tr><th colspan=4>%llu data values in this window view</th></tr>\n", valuesMatched);
+	printf("<tr><th>chromosome</th><th>chromStart</th><th>chromEnd</th><th>dataValue</th></tr>\n");
+        printf("</thead>\n");
+        printf("<tbody>\n");
+	printf("%s", dyStringCannibalize(&tableData));
+        printf("</tbody>\n");
+        printf("<tfoot>\n");
+	printf("<tr><td colspan=4>compressed data has resolution of + or - %.3f</td></tr>\n", worstCaseResolution);
+        printf("</tfoot>\n");
+        printf("</table>\n");
+	}
+    else
+	{
 	/*	If we have a valid range, use a specified 20 bin histogram
 	 *	NOTE: pass 21 as binCount to get a 20 bin histogram
 	 */
 	if (hRange > 0.0)
 	    histoGramResult = histoGram(valuesArray, valueCount, (hRange/20.0),
 	        (unsigned) 21, hMin, hMin, hMax, (struct histoResult *)NULL);
 	else
 	    histoGramResult = histoGram(valuesArray, valueCount,
 	        NAN, (unsigned) 0, NAN, (float) wds->stats->lowerLimit,
 		    (float) (wds->stats->lowerLimit + wds->stats->dataRange),
 		        (struct histoResult *)NULL);
 
 	/*	histoGram() may return NULL if it doesn't work, that's OK, the
 	 *	print out will indicate no results  (TRUE == html output)
 	 */
 	printHistoGram(histoGramResult, TRUE);
 
 	freeHistoGram(&histoGramResult);
+	}
     freeMem(valuesArray);
     }
 else
     {
     printf("<P>(viewing windows of fewer than %s bases will also"
 	" display a histogram)</P>\n", MAX_WINDOW_ALLOW_STRING);
     }
 
 wiggleDataStreamFree(&wds);
 }
 
 void bbiIntervalStatsReport(struct bbiInterval *bbList, char *table, 
 	char *chrom, bits32 start, bits32 end)
 /* Write out little statistical report in HTML */
 {