5bfb32fdfc639f9bffb5435044cef164bdde0b28 kent Sun Dec 12 08:02:13 2021 -0800 Implementing barChartMerge trackDb option for faceted bar charts. diff --git src/hg/lib/facetField.c src/hg/lib/facetField.c index a2b3553..80c3940 100644 --- src/hg/lib/facetField.c +++ src/hg/lib/facetField.c @@ -61,30 +61,56 @@ return newList; } static struct facetVal *facetValNew(char *val, int useCount) /* Create new facetVal structure */ { struct facetVal *facetVal; AllocVar(facetVal); facetVal->val = val; facetVal->useCount = useCount; return facetVal; } +int facetFieldCountSelected(struct facetField *facetField) +/* Return number of facets in list that are selected */ +{ +if (facetField->allSelected) + return slCount(facetField->valList); +else + { + int count = 0; + struct facetVal *facetVal; + for (facetVal = facetField->valList; facetVal != NULL; facetVal = facetVal->next) + if (facetVal->selected) + ++count; + return count; + } +} + +boolean facetFieldAnyMerged(struct facetField *list) +/* Return TRUE if any facetField on list isMerged */ +{ +struct facetField *facetField; +for (facetField = list; facetField != NULL; facetField = facetField->next) + if (facetField->isMerged) + return TRUE; +return FALSE; +} + static void facetFieldAdd(struct facetField *facetField, char *tagVal, boolean selecting) /* Add information about tag to facetField */ { if (!selecting) facetField->useCount += 1; struct facetVal *facetVal = hashFindVal(facetField->valHash, tagVal); if (facetVal == NULL) { AllocVar(facetVal); hashAddSaveName(facetField->valHash, tagVal, facetVal, &facetVal->val); slAddHead(&facetField->valList, facetVal); if (selecting) { facetVal->selected = TRUE; facetField->allSelected = FALSE; @@ -151,31 +177,31 @@ // shown on GUI to guide choosing by user } } return result; } #define facetValStringPunc '~' char *linearizeFacetVals(struct facetField *selectedList) /* Linearize selected fields vals into a string. fieldVal must be selected. */ { struct dyString *dy = newDyString(1024); struct facetField *sff = NULL; for (sff = selectedList; sff; sff=sff->next) { - dyStringPrintf(dy, "%s %d ", sff->fieldName, sff->showAllValues); + dyStringPrintf(dy, "%s %d%d ", sff->fieldName, sff->showAllValues, sff->isMerged); boolean first = TRUE; struct facetVal *el; for (el=sff->valList; el; el=el->next) { if (el->selected) { if (first) { first = FALSE; } else dyStringAppendC(dy, ','); // TODO encode as csv val to support doubled internal quote value? dyStringPrintf(dy, "\"%s\"", el->val); } @@ -219,125 +245,131 @@ { facetFieldAdd(sff, facetValue, TRUE); sff->currentVal->selected = FALSE; } else if (sameString(op, "showAllValues")) // show all facet values { sff->showAllValues = TRUE; } else if (sameString(op, "showSomeValues")) // show all facet values { sff->showAllValues = FALSE; } else if (sameString(op, "reset")) { sff->showAllValues = FALSE; + sff->isMerged = FALSE; struct facetVal *el; for (el=sff->valList; el; el=el->next) { el->selected = FALSE; } } +else if (sameString(op, "merge")) + { + sff->isMerged = TRUE; + } +else if (sameString(op, "unmerge")) + { + sff->isMerged = FALSE; + } *pSelectedList = selectedList; } struct facetField *deLinearizeFacetValString(char *selectedFields) /* Turn linearized selected fields string back into facet structures */ { struct facetField *ffList = NULL, *ff; boolean done = FALSE; while (!done) { if (sameString(selectedFields, "")) break; char *end = strchr(selectedFields, facetValStringPunc); if (!end) { end = selectedFields + strlen(selectedFields); done = TRUE; } char saveEnd = *end; *end = 0; char *spc = strchr(selectedFields, ' '); if (!spc) errAbort("expected space separating fieldname from showAllValues boolean"); *spc = 0; - char *showAllValuesBoolean = spc+1; - char *spc2 = strchr(showAllValuesBoolean, ' '); + char *flagsBoolean = spc+1; + char *spc2 = strchr(flagsBoolean, ' '); if (!spc2) errAbort("expected space separating showAllValues boolean from facet values list"); *spc2 = 0; char *vals = spc2+1; struct slName *valList = NULL; if (*vals != 0) // we have something valList = csvParse(vals); ff = facetFieldNew(selectedFields); - ff->showAllValues = (*showAllValuesBoolean == '1'); + ff->showAllValues = (flagsBoolean[0] == '1'); + ff->isMerged = (flagsBoolean[1] == '1'); slAddHead(&ffList, ff); struct slName *el; for (el=valList; el; el=el->next) { - //uglyf("adding selected field %s val %s\n", selectedFields, el->name); facetFieldAdd(ff, el->name, TRUE); } *spc = ' '; // restore *spc2 = ' '; // restore *end = saveEnd; selectedFields = end+1; } slReverse(&ffList); return ffList; } struct facetField *facetFieldsFromSqlTableInit(char *fields[], int fieldCount, char *selectedFields, struct facetField *ffArray[]) /* Initialize ffList and ffArray and selected facet values */ { /* Create facetField list and table. */ struct facetField *ffList = NULL, *ff; int i; for (i=0; inext) { - //warn("facetFieldsFromSqlTableInit: looking for ff->fieldName [%s]\n", sff->fieldName); // TODO REMOVE DEBUG for (i=0; ifieldName, sff->fieldName)) { - //warn("facetFieldsFromSqlTableInit: found ffArray[%d]->fieldName [%s]\n", i, ffArray[i]->fieldName); // TODO REMOVE DEBUG ffArray[i]->showAllValues = sff->showAllValues; + ffArray[i]->isMerged = sff->isMerged; struct facetVal *el; for (el=sff->valList; el; el=el->next) { - //warn("adding selected field %s val %s\n", sff->fieldName, el->val); // TODO REMOVE DEBUG facetFieldAdd(ffArray[i], el->val, TRUE); } } } } } return ffList; } void facetFieldsFromSqlTableFinish(struct facetField *ffList, int (*compare )(const void *elem1, const void *elem2)) /* Do final cleanup after passing over rows */ { /* Sort lists */ struct facetField *ff; @@ -378,39 +410,40 @@ if (perRowFacetFields(fieldCount, row, nullVal, ffArray)) ++selectedRowCount; } facetFieldsFromSqlTableFinish(ffList, facetValCmpUseCountDesc); /* Clean up and go home */ dyStringFree(&query); sqlFreeResult(&sr); if (pSelectedRowCount) *pSelectedRowCount = selectedRowCount; return ffList; } -struct fieldedTable *facetFieldsFromFieldedTable(struct fieldedTable *ft, char *selectedFields, +// struct fieldedTable *facetFieldsFromFieldedTable(struct fieldedTable *ft, char *selectionKey, +struct fieldedTable *facetFieldSelectRows(struct fieldedTable *ft, char *selectionKey, struct facetField *ffArray[]) -/* Get a facetField list and initialize arrays based on selected fields from table - * ffArray must be big enough to hold all fields in table */ +/* Return a tables that is just rows of table ft that pass selection key. ffArray should + * have same number of elements as ft->fieldCount */ { int fieldCount = ft->fieldCount; struct fieldedTable *subTable = fieldedTableNew(ft->name, ft->fields, fieldCount); struct facetField *ffList = facetFieldsFromSqlTableInit(ft->fields, fieldCount, - selectedFields, ffArray); + selectionKey, ffArray); struct fieldedRow *fr; for (fr = ft->rowList; fr != NULL; fr = fr->next) { if (perRowFacetFields(fieldCount, fr->row, "", ffArray)) { fieldedTableAdd(subTable, fr->row, fieldCount, fr->id); } } facetFieldsFromSqlTableFinish(ffList, facetValCmpUseCountDesc); return subTable; } struct facetVal *facetValMajorPlusOther(struct facetVal *list, double minRatio) /* Return a list of only the tags that are over minRatio of total tags. * If there are tags that have smaller amounts than this, lump them together