10856033c3d0f2ec024b90b3a29a4af692e86e6a braney Sun Apr 20 20:26:56 2014 -0700 stacked bars in multiwig working diff --git src/hg/hgTracks/multiWig.c src/hg/hgTracks/multiWig.c index 6339e1f..994bb52 100644 --- src/hg/hgTracks/multiWig.c +++ src/hg/hgTracks/multiWig.c @@ -172,61 +172,68 @@ /* Turns out to be *much* shorter to rewrite than to reuse preDrawAutoScale */ double max = -BIGDOUBLE, min = BIGDOUBLE; struct slRef *ref; int numTrack = 0; for (ref = refList; ref != NULL; numTrack++,ref = ref->next) { struct preDrawContainer *pre = ref->val; if (pre == NULL) // pre may be null if the bigWig file didn't load continue; struct preDrawElement *p = pre->preDraw + pre->preDrawZero; int width = pre->width; int i; int offset = numTrack * pre->width; int prevOffset = (numTrack - 1) * pre->width; - for (i=0; i<width; ++i, offset++) + for (i=0; i<width; ++i, offset++,prevOffset++) { double val; switch(windowingFunction) { case wiggleWindowingMean: val = p->sumData / p->count; break; case wiggleWindowingWhiskers: case wiggleWindowingMax: val = p->max; break; case wiggleWindowingMin: val = p->min; break; } if (p->count) { - if (min > val) min = val; - if (max < val) max = val; if (yOffsets) yOffsets[offset] = val; + else + { + if (min > val) min = val; + if (max < val) max = val; + } } else if (yOffsets) { yOffsets[offset] = 0; } - if (yOffsets && (prevOffset > 0)) + if (yOffsets && (numTrack > 0)) + { yOffsets[offset] += yOffsets[prevOffset]; + if (min > yOffsets[offset]) min = yOffsets[offset]; + if (max < yOffsets[offset]) max = yOffsets[offset]; + } ++p; } } if (alwaysZero == wiggleAlwaysZeroOn) { if ( max < 0) max = 0.0; else if ( min > 0) min = 0.0; } *retMax = max; *retMin = min; } @@ -279,67 +286,71 @@ numTracks++; if (subtrack->networkErrMsg) errMsgFound = TRUE; } } if (errMsgFound) { Color yellow = hvGfxFindRgb(hvg, &undefinedYellowColor); hvGfxBox(hvg, xOff, yOff, width, tg->height, yellow); } struct wigCartOptions *wigCart = tg->extraUiData; struct wigGraphOutput *wgo = setUpWgo(xOff, yOff, width, tg->height, numTracks, wigCart, hvg); -/* Cope with autoScale - we do it here rather than in the child tracks, so that +/* Cope with autoScale and stacked bars - we do it here rather than in the child tracks, so that * all children can be on same scale. */ -if (wigCart->autoScale) +double minVal, maxVal; +if (wigCart->autoScale || (wigCart->aggregateFunction == wiggleAggregateStacked)) { /* Force load of all predraw arrays so can do calcs. Build up list, and then * figure out max/min. No worries about multiple loading, the loaders protect * themselves. */ struct slRef *refList = NULL; for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (isSubtrackVisible(subtrack)) { struct preDrawContainer *pre = subtrack->loadPreDraw(subtrack, seqStart, seqEnd, width); refAdd(&refList, pre); } } - double minVal, maxVal; + slReverse(&refList); minMaxVals(refList, &minVal, &maxVal, wigCart->windowingFunction, wigCart->alwaysZero, wgo->yOffsets); slFreeList(&refList); + if (wigCart->autoScale) + { /* Cope with log transform if need be */ if (wigCart->transformFunc == wiggleTransformFuncLog) { minVal = wiggleLogish(minVal); maxVal = wiggleLogish(maxVal); } /* Loop through again setting up the wigCarts of the children to have minY/maxY for * our limits and autoScale off. */ for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next) { struct wigCartOptions *wigCart = subtrack->extraUiData; wigCart->minY = minVal; wigCart->maxY = maxVal; wigCart->autoScale = wiggleScaleManual; } } + } int numTrack = 0; for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (isSubtrackVisible(subtrack)) { if (!subtrack->networkErrMsg || !errMsgShown) { if (subtrack->networkErrMsg) errMsgShown = TRUE; wgo->numTrack = numTrack++; subtrack->wigGraphOutput = wgo; int height = subtrack->totalHeight(subtrack, vis); hvGfxSetClip(hvg, xOff, y, width, height); if (wigCart->aggregateFunction != wiggleAggregateNone)