ddb85ced5e8b6127a233b5cda5fcb1fbe2260578
max
  Wed Mar 25 04:22:06 2026 -0700
Add detailsScript trackDb mechanism for JS visualizations on bigBed details pages

Changing based on feedback from Jonathan, Chris and Brian after group
discussion. Refactored existing Claude-generated code, moving functions
into libraries.

This is the first use of ES6 modules in the kent js code. In 2026, this
should be acceptable?

New trackDb syntax: detailsScript.<plotType>.<fieldName> <jsonConfig>
The C code (bigBedClick.c) collects these settings, exports field values as JSON
(bedDetails object), and dynamically imports hgc.<plotType>.js as an ES6 module.
Fields used by detailsScript are shown in the HTML table with empty values,
filled by JavaScript.

Includes hgc.histogram.js module for drawing SVG bar chart histograms from
logfmt-encoded data (space-separated key=value pairs). Applied to both the
trexplorer and webstr tracks in the strVar supertrack.

Also adds jsonWriteJsonElement() helper to jsonWrite.c for writing parsed
jsonElement trees into a jsonWrite stream.

max, refs #36652
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

diff --git src/inc/jsonWrite.h src/inc/jsonWrite.h
index a86cca487b1..d74cba9742e 100644
--- src/inc/jsonWrite.h
+++ src/inc/jsonWrite.h
@@ -87,21 +87,24 @@
 
 void jsonWriteBoolean(struct jsonWrite *jw, char *var, boolean val);
 /* Write out "var": true or "var": false depending on val (no quotes around true/false). */
 
 void jsonWriteValueLabelList(struct jsonWrite *jw, char *var, struct slPair *pairList);
 /* Print out a named list of {"value": "<pair->name>", "label": "<pair->val>"} objects. */
 
 void jsonWriteSlNameList(struct jsonWrite *jw, char *var, struct slName *slnList);
 /* Print out a named list of strings from slnList. */
 
 void jsonWriteAppend(struct jsonWrite *jwA, char *var, struct jsonWrite *jwB);
 /* Append jwB's contents to jwA's.  If jwB is non-NULL, it must be fully closed (no unclosed
  * list or object).  If var is non-NULL, write it out as a tag before appending.
  * If both var and jwB are NULL, leave jwA unchanged. */
 
+void jsonWriteJsonElement(struct jsonWrite *jw, char *var, struct jsonElement *el);
+/* Write a jsonElement (parsed JSON) into jw.  Handles all types recursively. */
+
 int jsonWritePopToLevel(struct jsonWrite *jw, uint level);
 /* Close out the objects and lists that are deeper than level, so we end up at level ready to
  * add new items.  Return the level that we end up with, which may not be the same as level,
  * if level is deeper than the current stack. */
 
 #endif /* JSONWRITE_H */