0b780ebaab52c71cce8e8dc15c8540eb94e3a1bf
chmalee
Tue Aug 5 15:23:07 2025 -0700
Draw the barChart svgs on the client so the table can take advantage of the full screen width, refs #36124
diff --git src/hg/hgc/barChartClick.c src/hg/hgc/barChartClick.c
index eb27e10ce94..7cb1d54f446 100644
--- src/hg/hgc/barChartClick.c
+++ src/hg/hgc/barChartClick.c
@@ -15,30 +15,31 @@
#include "trackHub.h"
#include "memgfx.h"
#include "hgColors.h"
#include "fieldedTable.h"
#include "barChartBed.h"
#include "barChartCategory.h"
#include "barChartData.h"
#include "barChartSample.h"
#include "barChartUi.h"
#include "hgConfig.h"
#include "facetedBar.h"
#include "pipeline.h"
#include "chromAlias.h"
#include "jsHelper.h"
+#include "jsonWrite.h"
#define EXTRA_FIELDS_SIZE 256
struct barChartItemData
/* Measured value for a sample and the sample category at a locus.
* Used for barChart track details (boxplot) */
{
struct barChartItemData *next; /* Next in singly linked list. */
char *sample; /* Sample identifier */
char *category; /* Sample category (from barChartSample table or barChartSampleUrl file) */
double value; /* Measured value (e.g. expression level) */
};
struct barChartPlusRow
/* Keep original row around for url processing */
@@ -383,54 +384,30 @@
bool useOldFonts = cgiBoolean("oldFonts");
/* Exec R in quiet mode, without reading/saving environment or workspace */
char *pipeCmd[] = {"Rscript","--vanilla","--slave","hgcData/barChartBoxplot.R",
item, units, colorFile, df, pngTn.forHtml,
isEmpty(name2) ? "n/a" : name2, useOldFonts ? "1" : "0", NULL};
struct pipeline *pl = pipelineOpen1(pipeCmd, pipelineWrite | pipelineNoAbort, "/dev/null", NULL, 0);
int ret = pipelineWait(pl);
if (ret == 0)
printf("
\n", pngTn.forHtml);
else
warn("Error creating boxplot from sample data with command: %s", pipelineDesc(pl));
}
-static double estimateStringWidth(char *s)
-/* Get estimate of string width based on a memory font that is about the
- * same size as svg will be using. After much research I don't think we
- * can get the size from the server, would have to be in Javascript to get
- * more precise */
-{
-MgFont *font = mgHelvetica14Font();
-return mgFontStringWidth(font, s);
-}
-
-static double longestLabelSize(struct barChartCategory *categList)
-/* Get estimate of longest label in pixels */
-{
-int longest = 0;
-struct barChartCategory *categ;
-for (categ = categList; categ != NULL; categ = categ->next)
- {
- int size = estimateStringWidth(categ->label);
- if (size > longest)
- longest = size;
- }
-return longest * 1.02;
-}
-
void deunderbarColumn(struct fieldedTable *ft, int fieldIx)
/* Ununderbar all of a column inside table because space/underbar gets
* so confusing */
{
struct fieldedRow *row;
for (row = ft->rowList; row != NULL; row = row->next)
replaceChar(row->row[fieldIx], '_', ' ');
}
static void svgBarChart(struct barChartBed *chart, struct trackDb *tdb, double maxVal, char *metric)
/* Plot bar chart without quartiles or anything fancy just using SVG */
{
jsIncludeFile("hgc.js", NULL);
puts("
"); /* Load up input labels, color, and data */ @@ -446,99 +423,72 @@ char *statsFile = hReplaceGbdb(trackDbSetting(tdb, "barChartStatsUrl")); struct hash *statsHash = NULL; int countStatIx = 0; double statsSize = 0.0; if (statsFile != NULL) { char *required[] = { "count", "total"}; struct fieldedTable *ft = fieldedTableFromTabFile( statsFile, statsFile, required, ArraySize(required)); deunderbarColumn(ft, 0); statsHash = fieldedTableIndex(ft, ft->fields[0]); countStatIx = fieldedTableFindFieldIx(ft, "count"); statsSize = 8*(fieldedTableMaxColChars(ft, countStatIx)+1); } -/* Some constants that control layout */ -double heightPer=18.0; -double totalWidth=1250.0; -double borderSize = 1.0; - -double headerHeight = heightPer + 2*borderSize; -double innerHeight=heightPer-borderSize; -double labelWidth = longestLabelSize(categs) + 9; // Add some because size is just estimate -if (labelWidth > totalWidth/2) labelWidth = totalWidth/2; // Don't let labels take up more than half -double patchWidth = heightPer; -double labelOffset = patchWidth + 2*borderSize; -double statsOffset = labelOffset + labelWidth; -double barOffset = statsOffset + statsSize; -double statsRightOffset = barOffset - 9; -double barNumLabelWidth = estimateStringWidth(" 1234.000"); -double barMaxWidth = totalWidth-barOffset -barNumLabelWidth ; -double totalHeight = headerHeight + heightPer * categCount + borderSize; - jsInline("var svgTable = true;\n"); -printf(""); +jsonWriteListEnd(jw); +jsonWriteObjectEnd(jw); +jsInlineF("var barChartValues = %s\n", jw->dy->string); +jsonWriteFree(&jw); +printf("\n", statsSize > 0.0 ? "true" : "false"); } static void printBarChart(char *item, struct barChartBed *chart, struct trackDb *tdb, double maxVal, char *metric) /* Plot bar chart without expressionMatrix or R plots*/ { char *statsFile = hReplaceGbdb(trackDbSetting(tdb, "barChartStatsUrl")); char *facets = trackDbSetting(tdb, "barChartFacets"); if (facets != NULL && statsFile != NULL) facetedBarChart(item, chart, tdb, maxVal, statsFile, facets, metric); else svgBarChart(chart, tdb, maxVal, metric); }