646ff06654a53214f1b47fa6b92742ec6a44934a kent Mon Dec 21 12:16:42 2020 -0800 Adding simple barchart display without box plots when no expMatrix available. diff --git src/hg/hgc/barChartClick.c src/hg/hgc/barChartClick.c index f83f479..ce2bac9 100644 --- src/hg/hgc/barChartClick.c +++ src/hg/hgc/barChartClick.c @@ -359,30 +359,78 @@ // to help with QAing the change, we add the "oldFonts" CGI parameter so QA can compare // old and new fonts to make sure that things are still readible on mirrors and servers // without the new fonts installed. This only needed during the QA phase bool useOldFonts = cgiBoolean("oldFonts"); /* Exec R in quiet mode, without reading/saving environment or workspace */ dyStringPrintf(cmd, "Rscript --vanilla --slave hgcData/barChartBoxplot.R %s '%s' %s %s %s %s %d", item, units, colorFile, df, pngTn.forHtml, isEmpty(name2) ? "n/a" : name2, useOldFonts); int ret = system(cmd->string); if (ret == 0) printf("<img src = \"%s\" border=1><br>\n", pngTn.forHtml); else warn("Error creating boxplot from sample data with command: %s", cmd->string); } +static void printBarChart(struct barChartBed *chart, struct trackDb *tdb, double maxVal) +/* Plot bar chart without quartiles or anything fancy just using SVG */ +{ +/* Load up input labels, color, and data */ +struct barChartCategory *categs = barChartUiGetCategories(database, tdb); +int categCount = slCount(categs); +if (categCount != chart->expCount) + { + warn("Problem in %s barchart track. There are %d categories in trackDb and %d in data", + tdb->track, categCount, chart->expCount); + return; + } + +double heightPer=18.0; +double innerHeight=heightPer-1; +double widthPer=1300.0; +double labelOffset = 20.0; +double barOffset = 260.0; +double barMaxWidth = widthPer-barOffset - 45; +double totalHeight = heightPer * categCount; + +printf("<svg width=\"%g\" height=\"%g\">\n", widthPer, totalHeight); +double yPos = 0.0; +int i; +struct barChartCategory *categ; + +printf("<clipPath id=\"labelClip\"><rect x=\"%g\" y=\"0\" width=\"%g\" height=\"%g\"/></clipPath>", + labelOffset, barOffset-labelOffset, totalHeight); +for (i=0, categ=categs; i<categCount; ++i , categ=categ->next, yPos += heightPer) + { + double score = chart->expScores[i]; + double barWidth = 0; + if (maxVal > 0.0) + barWidth = barMaxWidth * score/maxVal; + replaceChar(categ->label, '_', ' '); + printf("<rect x=\"0\" y=\"%g\" width=\"15\" height=\"%g\" style=\"fill:#%06X\"/>\n", + yPos, innerHeight, categ->color); + printf("<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:#%06X\"/>\n", + barOffset, yPos, barWidth, innerHeight, categ->color); + printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\" clip-path=\"url(#labelClip)\"\">%s</text>\n", + labelOffset, yPos+innerHeight-1, innerHeight-1, categ->label); + printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\">%5.3f</text>\n", + barOffset+barWidth+2, yPos+innerHeight-1, innerHeight-1, score); + } +printf("<svg>"); +} + + struct asColumn *asFindColByIx(struct asObject *as, int ix) /* Find AS column by index */ { struct asColumn *asCol; int i; for (i=0, asCol = as->columnList; asCol != NULL && i<ix; asCol = asCol->next, i++); return asCol; } void doBarChartDetails(struct trackDb *tdb, char *item) /* Details of barChart item */ { int start = cartInt(cart, "o"); int end = cartInt(cart, "t"); struct asObject *as = NULL; @@ -399,61 +447,66 @@ struct asColumn *nameCol = NULL, *name2Col = NULL; //struct asColumn *name2Col; char *nameLabel = NULL, *name2Label = NULL; if (as != NULL) { numColumns = slCount(as->columnList); nameCol = asFindColByIx(as, BARCHART_NAME_COLUMN_IX); name2Col = asFindColByIx(as, BARCHART_NAME2_COLUMN_IX); } nameLabel = trackDbSettingClosestToHomeOrDefault(tdb, "bedNameLabel", nameCol ? nameCol->comment : "Item"); if (trackDbSettingClosestToHomeOrDefault(tdb, "url", NULL) != NULL) printCustomUrl(tdb, item, TRUE); else printf("<b>%s: </b>%s<br>\n", nameLabel, chartItem->name); name2Label = name2Col ? name2Col->comment : "Alternative name"; -if (differentString(chartItem->name2, "")) { +if (differentString(chartItem->name2, "")) + { if (trackDbSettingClosestToHomeOrDefault(tdb, "url2", NULL) != NULL) printOtherCustomUrl(tdb, chartItem->name2, "url2", TRUE); else printf("<b>%s: </b> %s<br>\n", name2Label, chartItem->name2); } int categId; float highLevel = barChartMaxValue(chartItem, &categId); char *units = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_UNIT, "units"); char *metric = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_METRIC, ""); printf("<b>Total all %s values: </b> %0.2f %s<br>\n", metric, barChartTotalValue(chartItem), units); printf("<b>Maximum %s value: </b> %0.2f %s in %s<br>\n", metric, highLevel, units, barChartUiGetCategoryLabelById(categId, database, tdb)); printf("<b>Score: </b> %d<br>\n", chartItem->score); printf("<b>Genomic position: " "</b>%s <a href='%s&db=%s&position=%s%%3A%d-%d'>%s:%d-%d</a><br>\n", database, hgTracksPathAndSettings(), database, chartItem->chrom, chartItem->chromStart+1, chartItem->chromEnd, chartItem->chrom, chartItem->chromStart+1, chartItem->chromEnd); printf("<b>Strand: </b> %s\n", chartItem->strand); // print any remaining extra fields if (numColumns > 0) { extraFieldsPrint(tdb, NULL, extraFields, extraFieldCount); } char *matrixUrl = NULL, *sampleUrl = NULL; struct barChartItemData *vals = getSampleVals(tdb, chartItem, &matrixUrl, &sampleUrl); +puts("<p>"); if (vals != NULL) { // Print boxplot - puts("<p>"); char *df = makeDataFrame(tdb->table, vals); char *colorFile = makeColorFile(tdb); printBoxplot(df, item, chartItem->name2, units, colorFile); printf("<br><a href='%s'>View all data points for %s%s%s%s</a>\n", df, chartItem->name, chartItem->name2 ? " (" : "", chartItem->name2 ? chartItem->name2 : "", chartItem->name2 ? ")" : ""); } +else + { + printBarChart(chartItem, tdb, highLevel); + } puts("<br>"); }