/// /// DrawingCanvas::useWhiteInk() /// /// /// bool DrawingCanvas::useWhiteInk(Individual *pIndividual){ // // How many sections are there? // unsigned sections = pIndividual->getDataTable()->getIconColumnCount(); if(!sections){ return false; }else{ const DataTable * pDT = pIndividual->getDataTable(); // // Well, we are only going to look at the first section of the pie // even if there are multiple sections ... // DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(0) ); const UniqueList * pUL = pDC->getUniqueList(); // // Only process if there are some non-missing levels present: // if(!pUL->getLevels()){ return false; }else{ // // What is the level and label in the UniqueList corresponding to the data value // for this individual? // unsigned level; std::string label; pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level ); // // UniqueList ordinals are 1-offset, so we should only get zero back // if the key was not found, which should never happen: // if(level==0) throw Exception("DrawingCanvas::useWhiteInk()","UniqueList returned ordinal 0."); // // Level is 1-offset, so subtract: // level--; // // Get the color series corresponding to this icon column: // ColorSeries *pCS; if(DrawingMetrics::getColor()){ pCS = pDT->getColorSeriesFromStack(0); }else{ pCS = pDT->getBlackAndWhiteSeriesFromStack(0); } if(pCS->useBlackInkAtLevel(level)){ return false; }else{ return true; } } } }
/// /// toggleColumnsForPedigree(): User can specify any number of columns to be displayed on the pedigree. /// Mark all such columns for output display, if they exist. /// void DataTable::toggleColumnsForPedigree(const std::vector<std::string> &columns){ // Since the labels are specified by the user clear the vector that contains // the default label 'Individual Id' _labelColumns.clear(); for(unsigned i=0;i<columns.size();i++){ if(columnExists(columns[i])){ DataColumn* dc = getColumn(stringToUpper(columns[i]).c_str()); dc->setShowOnPedigree(true); _labelColumns.push_back(dc->getOrdinal()); }else Warning("DataTable::toggleColumnsForPedigree","Could not find column %s to show on the pedigree.",columns[i].c_str()); } }
void DataChart::Load(Simulator *lpSim, CStdXml &oXml) { short iColumn, iTotalColumns; ActivatedItem::Load(lpSim, oXml); oXml.IntoElem(); //Into DataChart Element if(m_aryDataBuffer) delete[] m_aryDataBuffer; m_aryDataBuffer = NULL; m_aryDataColumns.RemoveAll(); float fltCollectInterval = oXml.GetChildFloat("CollectInterval"); Std_IsAboveMin((float) 0, fltCollectInterval, TRUE, "CollectInterval"); //Lets calculate the number of slices for the collect interval. m_iCollectInterval = (int) (fltCollectInterval/lpSim->TimeStep()); if(m_iCollectInterval<=0) m_iCollectInterval = 1; if(!oXml.FindChildElement("SetStartEndTime", FALSE)) { m_bSetStartEndTime = oXml.GetChildBool("SetStartEndTime", TRUE); m_fltCollectTimeWindow = oXml.GetChildFloat("CollectTimeWindow", -1); } else { m_bSetStartEndTime = TRUE; m_fltCollectTimeWindow = -1; } //*** Begin Loading DataColumns. ***** oXml.IntoChildElement("DataColumns"); iTotalColumns = oXml.NumberOfChildren(); DataColumn *lpColumn = NULL; for(iColumn=0; iColumn<iTotalColumns; iColumn++) { oXml.FindChildByIndex(iColumn); lpColumn = LoadDataColumn(lpSim, oXml); if(lpColumn->Index() < 0) lpColumn->Index(iColumn); } oXml.OutOfElem(); //*** End Loading DataColumns. ***** oXml.OutOfElem(); //OutOf DataChart Element }
Attribute::Attribute(const DataColumn& col) { totalUnique = 0; name = col.Name(); PopulateMaps(col); totalEntities = col.size; }
DataColumn *DataChart::FindColumn(string strID, int &iIndex, BOOL bThrowError) { int iCount = m_aryDataColumns.GetSize(); DataColumn *lpColumn = NULL; strID = Std_CheckString(strID); for(iIndex=0; iIndex<iCount; iIndex++) { lpColumn = m_aryDataColumns[iIndex]; if(lpColumn->ID() >= strID) return lpColumn; } if(bThrowError) THROW_TEXT_ERROR(Al_Err_lDataColumnIDNotFound, Al_Err_strDataColumnIDNotFound, " DataColumn ID: " + strID); return NULL; }
// // addPedigreesFromDataTable(): // void PedigreeSet::addPedigreesFromDataTable(const DataTable * p_pedigreeTable, unsigned tableIndex,const std::string& sortField){ // // Use const reference for convenience: // (so I don't have to change the code // since the parameter has changed from a // const DataTable & to a const DataTable * ) // const DataTable & pedigreeTable = (*p_pedigreeTable); std::cout << "Start of addPedigreesFromDataTable" << std::endl; // // Get all the core columns from the datatable: // DataColumn *familyIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.FamilyIdField ); //familyIdColumn->printData(); DataColumn *individualIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.IndividualIdField ); //individualIdColumn->printData(); DataColumn *motherIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.MotherIdField ); DataColumn *fatherIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.FatherIdField ); DataColumn *genderColumn = pedigreeTable.getColumn( pedigreeTable.labels.GenderField ); // // Insert the Pedigrees in a set: // std::string currentFamily; int numberOfRows = familyIdColumn->getNumberOfRows(); int index=0; while(index < numberOfRows){ currentFamily = familyIdColumn->get(index); if(currentFamily == "."){ Warning("PedigreeSet::addPedigreesFromDataTable()", "Family Id is missing for individual %s and will be ignored.", individualIdColumn->get(index).c_str() ); index++; continue; } std::pair<std::set<Pedigree*,comparePedigrees>::iterator,bool> pp; pp = _pedigrees.insert(new Pedigree(currentFamily,tableIndex)); if(pp.second){ for(int i=0;i<familyIdColumn->getNumberOfRows();i++) { if(currentFamily.compare(familyIdColumn->get(i)) == 0){ (*pp.first)->addIndividual(individualIdColumn->get(i),motherIdColumn->get(i),fatherIdColumn->get(i),genderColumn->get(i),i,tableIndex,pedigreeTable); } } } index++; } // Set the core optional fields on the individuals _setCoreOptionalFields(p_pedigreeTable); _establishConnections(); bool dobPresent = false; if(pedigreeTable.getDOBColumnIndex() != DataTable::COLUMN_IS_MISSING){ _checkParentChildDOB(); dobPresent = true; } _determineFoundingGroups(); bool sortFieldPresent = false; if(sortField != std::string("") && sortField != pedigreeTable.labels.DOBField){ // Check to see if the field actually exists in the data table if(pedigreeTable.columnExists(sortField)){ _computeWidths(sortField); sortFieldPresent = true; }else{ Warning("PedigreeSet::addPedigreesFromDataTable()", "Field '%s' specified for sorting the siblings does not exist in the Pedigree Table. Default ordering will be used.", sortField.c_str() ); } } if(!sortFieldPresent){ if(dobPresent){ std::cout << "Siblings are ordered by DOB." << std::endl; _computeWidths(pedigreeTable.labels.DOBField,true); DrawingMetrics::setDisplayBirthOrder(true); }else{ std::cout << "Default ordering of siblings." << std::endl; _computeWidths(std::string("")); } } std::cout << "End of addPedigreesFromDataTable" << std::endl; }
/// /// iconPie(): Draws a pie with a given color on the individual icon. Each pie corresponds to one /// categorical variable. The color corresponds to the level in that variable. /// void DrawingCanvas::iconPie( double x, double y, Individual *pIndividual ){ // // Handle virtual individuals: // if(pIndividual->isVirtual()){ //_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\""; //_body << " class=\"thinLine\""; //_body << "/>\n"; return; } // // Get here if non-virtual: // // // How many sections are there? // unsigned sections = pIndividual->getDataTable()->getIconColumnCount(); if(!sections){ // // No affected fields : Draw a small circle in the middle: // (Nice for debugging -- otherwise comment out ) // //_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\""; //_body << " class=\"thinLine\""; //_body << "/>\n"; return; } // // Setup clipping Id, if needed: // std::string clipId = pIndividual->getId().get() + "_clipPath"; double radius=DrawingMetrics::getIconRadius(); bool isMale = false; if( pIndividual->getGender().getEnum()==Gender::MALE ){ setClipPath(x,y,clipId); // // Increase radius for clipping: // radius*=Number::SQRT_TWO; isMale = true; _body << "<g clip-path=\"url(#" << clipId << ")\">\n"; }else{ // // Empty g with no clipping for female: // _body << "<g>\n"; } // // Iterate over _iconColumns: // const DataTable *pDT = pIndividual->getDataTable(); double arcAngle = 2.0*Number::PI/sections; double startAngle = 0.5*Number::PI - arcAngle; double endAngle = startAngle+arcAngle; for(unsigned i=0;i<sections;i++){ // // Get the data column of the ith icon column: // DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(i) ); // // Get the UniqueList for this column: // const UniqueList * pUL = pDC->getUniqueList(); // // Only process if there are some non-missing levels // present: // if(!pUL->getLevels()) continue; // // What is the level and label in the UniqueList corresponding to the data value // for this individual? // unsigned level; std::string label; pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level ); // // UniqueList ordinals are 1-offset, so we should only get zero back // if the key was not found, which should never happen: // if(level==0) throw Exception("DrawingCanvas::iconPie()","UniqueList returned ordinal 0."); // // Level is 1-offset, so subtract: // level--; // // Get the color series corresponding to this icon column: // // NOTA BENE: (1) IF there is only one section, we use the // blackAndWhite series // UNLESS there is a color override. // // (2) OTHERWISE if there are more than one section, // we use the color series // UNLESS there is a black-and-white override. // ColorSeries *pCS; if(sections==1){ if(DrawingMetrics::getColor()) pCS = pDT->getColorSeriesFromStack(i); else pCS = pDT->getBlackAndWhiteSeriesFromStack(i); }else{ if(DrawingMetrics::getBlackAndWhite()) pCS = pDT->getBlackAndWhiteSeriesFromStack(i); else pCS = pDT->getColorSeriesFromStack(i); } // // Assume reversed for now: // bool reversed=true; std::string arcClass="blackInkLetter"; if(!pCS->reversedSeriesUseBlackInkAtLevel(level)) arcClass="whiteInkLetter"; // // If the number of sections is small, use a larger font size // if(sections == 1) arcClass += "_1"; else if(sections == 2) arcClass += "_2"; else if(sections == 3) arcClass += "_3"; arc(x,y,radius,startAngle,endAngle,(reversed?pCS->reversedSeriesGetColorAtLevel(level):pCS->getColorAtLevel(level)),label,arcClass,isMale); startAngle+=arcAngle; endAngle+=arcAngle; // For the first time draw the icon legend too: if(!_iconLegendFlag){ _iconLegendFlag = true; _iconLegend.setPedigreeTable(pDT); } } _body << "</g>\n"; return; }
/// /// iconQuadrantFill(): Shade quadrants of the icon to indicate specific levels. /// This method has a limit of 16 distinct levels. /// void DrawingCanvas::iconQuadrantFill( double x, double y, Individual *pIndividual ){ // // Handle virtual individuals: // if(pIndividual->isVirtual()){ return; } // // Get here if non-virtual: // // // How many sections are there? // unsigned sections = pIndividual->getDataTable()->getIconColumnCount(); if(!sections){ // // No affected fields : Draw a small circle in the middle: // (Nice for debugging -- otherwise comment out ) // //_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\""; //_body << " class=\"thinLine\""; //_body << "/>\n"; return; } // // Setup clipping Id, if needed: // double radius=DrawingMetrics::getIconRadius(); bool isMale = false; if( pIndividual->getGender().getEnum()==Gender::MALE ){ std::string clipId = pIndividual->getId().get() + "_clipPath"; setClipPath(x,y,clipId); // // Increase radius for clipping: // radius*=Number::SQRT_TWO; isMale = true; _body << "<g clip-path=\"url(#" << clipId << ")\">\n"; }else{ // // Empty g with no clipping for female: // _body << "<g>\n"; } // // NOTA BENE: The quadrant fill method looks only at the // FIRST iconColumn and ignores any additional icon columns: // const DataTable *pDT = pIndividual->getDataTable(); // // Get the data column of the first icon column: // DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(0) ); // // Get the UniqueList for this column: // const UniqueList * pUL = pDC->getUniqueList(); // // Only process if there are some non-missing levels // present: // if(!pUL->getLevels()){ _body << "</g>\n"; return; } // // What is the level and label in the UniqueList corresponding to the data value // for this individual? // //unsigned level; //std::string label; //pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level ); // Data* data = pDC->getDataAtIndex( pIndividual->getRowIndex()); // // Draw a dot for missing values: // if(data->isMissing()){ drawText(x,y,".","blackInkLetter_1"); _body << "</g>\n"; return; } std::string label; std::string svalue = data->get(); std::istringstream i(svalue); int level; bool converted = (i>>level); if(!converted || level<0 || level>15 ){ // // (1) Unable to convert data string to integer, or // (2) integer value is out of range // double lineSpacing,xAdvance,yMinimum,yMaximum; _lasiWrapper.getDimensions(svalue,&lineSpacing,&xAdvance,&yMinimum,&yMaximum); y+= 0.5*(yMaximum-yMinimum); drawIconText(x,y,svalue,"blackInkLetter_1"); _body << "</g>\n"; return; } // // Fill arc for each quadrant based on level: // Note: Madeline's "arc()" method doesn't use the standard counter-clockwise quadrants // starting at 0, so the order of the 4 "if" statements below may appear mixed up but // this actually results in shading of the quadrants according to standard notation: // if(level & 0x02 ){ arc(x,y,radius,0,0.5*Number::PI,"#000",label,"whiteInkLetter",isMale); } if(level & 0x01 ){ arc(x,y,radius,0.5*Number::PI,Number::PI,"#000",label,"whiteInkLetter",isMale); } if(level & 0x08 ){ arc(x,y,radius,Number::PI,1.5*Number::PI,"#000",label,"whiteInkLetter",isMale); } if(level & 0x04 ){ arc(x,y,radius,1.5*Number::PI,2.0*Number::PI,"#000",label,"whiteInkLetter",isMale); } // // For the first time draw the icon legend too: // //if(!_iconLegendFlag){ // _iconLegendFlag = true; // _iconLegend.setPedigreeTable(pDT); //} _body << "</g>\n"; return; }
int SqliteClient::executeSqlQuery(const string& sql, DataTable& table) { Locker locker(&_sqliteDbMutex); #if DEBUG Stopwatch sw("executeSqlQuery", 100); #endif sqlite3_stmt *stmt; int result = sqlite3_prepare_v2(_sqliteDb, sql.c_str(), sql.length(), &stmt, 0); if(result != SQLITE_OK) { printErrorInfo("sqlite3_prepare_v2", sql); return result; } //const char* name = sqlite3_column_table_name(stmt, 0); //table.setName(name != NULL ? name : "temp"); // todo: linke error for sqlite3_column_table_name. table.setName("temp"); #if DEBUG sw.setInfo(Convert::convertStr("executeSqlQuery, the table name is '%s'", table.getName().c_str())); #endif int columnCount = sqlite3_column_count(stmt); for (int i = 0; i < columnCount; i++) { char* nameStr = (char*)sqlite3_column_name(stmt, i); string name; if(nameStr != NULL) { name = nameStr; } else { char temp[32]; sprintf(temp, "tempCol%d", i); name = temp; } const char* typeStr = sqlite3_column_decltype(stmt, i); string type = typeStr != NULL ? typeStr : "int"; DataColumn* column = new DataColumn(name, type); table.addColumn(column); } while(sqlite3_step(stmt) == SQLITE_ROW) { DataRow* row = new DataRow(); for (int i = 0; i < columnCount; i++) { DataColumn* column = table.getColumns()->at(i); DataCell* cell = NULL; Value value; memset(&value, 0, sizeof(value)); ValueTypes type = column->getType(); switch (type) { case Null: break; case Integer: value.nValue = sqlite3_column_int(stmt, i); break; case String: case DateTime: { char* str = (char*)sqlite3_column_text(stmt, i); DataCell::setStringValue(value, str); } break; case Float: value.dValue = sqlite3_column_double(stmt, i); break; default: assert(false); break; } cell = new DataCell(column, value); row->addCell(cell); } table.addRow(row); } result = sqlite3_finalize(stmt); if(result != SQLITE_OK) { printErrorInfo("sqlite3_finalize", sql); return result; } return SQLITE_OK; }
// // addPedigreesFromDataTable(): // void PedigreeSet::addPedigreesFromDataTable(const DataTable * p_pedigreeTable, unsigned tableIndex,const std::string& sortField){ // // Use const reference for convenience: // (so I don't have to change the code // since the parameter has changed from a // const DataTable & to a const DataTable * ) // const DataTable & pedigreeTable = (*p_pedigreeTable); //std::cout << vt100::startBlue << "┏ Start of addPedigreesFromDataTable ┓" << vt100::stopColor << std::endl; // // Get all the core columns from the datatable: // DataColumn *familyIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.FamilyIdField ); //familyIdColumn->printData(); DataColumn *individualIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.IndividualIdField ); //individualIdColumn->printData(); DataColumn *motherIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.MotherIdField ); DataColumn *fatherIdColumn = pedigreeTable.getColumn( pedigreeTable.labels.FatherIdField ); DataColumn *genderColumn = pedigreeTable.getColumn( pedigreeTable.labels.GenderField ); DataColumn *collapsedColumn= 0; if(pedigreeTable.columnExists(pedigreeTable.labels.CollapsedField)){ // 2015.11.30.ET ADDENDA: collapsedColumn=pedigreeTable.getColumn( pedigreeTable.labels.CollapsedField ); } // // Insert the Pedigrees in a set: // std::string currentFamily; int numberOfRows = familyIdColumn->getNumberOfRows(); int index=0; std::map<std::string,Individual *> collapsedIndicatorSet; Individual * collapsedIndividual=0; while(index < numberOfRows){ currentFamily = familyIdColumn->get(index); if(currentFamily == "."){ Warning("PedigreeSet::addPedigreesFromDataTable()", "Family Id is missing for individual %s and will be ignored.", individualIdColumn->get(index).c_str() ); index++; continue; } std::pair<std::set<Pedigree*,comparePedigrees>::iterator,bool> pp; pp = _pedigrees.insert(new Pedigree(currentFamily,tableIndex)); if(pp.second){ for(int i=0;i<familyIdColumn->getNumberOfRows();i++) { if(currentFamily.compare(familyIdColumn->get(i)) == 0){ /////////////////////////////////// // // Handle "collapsing": // /////////////////////////////////// if(DrawingMetrics::getCollapsible() && collapsedColumn){ std::string indicator=collapsedColumn->get(i); if(indicator=="."){ // Add normal, non-collapsed individual, as usual: (*pp.first)->addIndividual(individualIdColumn->get(i),motherIdColumn->get(i),fatherIdColumn->get(i),genderColumn->get(i),i,tableIndex,pedigreeTable); }else{ // // Handling collapsed individuals: // std::map<std::string,Individual *>::iterator it=collapsedIndicatorSet.find(indicator); if(it==collapsedIndicatorSet.end()){ // // Indicator not yet present in set, so add the first marked individual // as the token individual: // collapsedIndividual = (*pp.first)->addIndividual(individualIdColumn->get(i),motherIdColumn->get(i),fatherIdColumn->get(i),genderColumn->get(i),i,tableIndex,pedigreeTable); collapsedIndividual->incrementCollapsedCount(); collapsedIndicatorSet.insert(std::pair<std::string,Individual *>(indicator,collapsedIndividual)); // 2015.12.01.ET DEBUG std::cout << "*** Individual " << individualIdColumn->get(i) << " used for collapsed group " << indicator << std::endl; }else{ ////////////////////////////////////////////////// // // Is gender of new person consistent? // // Note: using Gender.getEnum() guarantees // symbolic equivalency across different // string representations, e.g. "M"=="male", // "♀"=="female", etc. // ////////////////////////////////////////////////// if( it->second->getGender().getEnum() != Gender(genderColumn->get(i)).getEnum() ){ // Change to missing on token individual: it->second->setGender("."); } ////////////////////////////////////////////////// // // Is affection status of new person consistent? // ////////////////////////////////////////////////// ////////////////////////////////////////////////// // // increment collapsed count: // ////////////////////////////////////////////////// it->second->incrementCollapsedCount(); // 2015.12.01.ET DEBUG // std::cout << "*** Individual " << it->second->getId() << " with indicator " << indicator << " incremented to " << it->second->getCollapsedCount() << std::endl; } } }else{ // CollapsedState OFF or Collapsed column not present, so just add everybody: (*pp.first)->addIndividual(individualIdColumn->get(i),motherIdColumn->get(i),fatherIdColumn->get(i),genderColumn->get(i),i,tableIndex,pedigreeTable); } } } } index++; } // Set the core optional fields on the individuals _setCoreOptionalFields(p_pedigreeTable); _establishConnections(); bool dobPresent = false; if(pedigreeTable.getDOBColumnIndex() != DataTable::COLUMN_IS_MISSING){ _checkParentChildDOB(); dobPresent = true; } if(pedigreeTable.getPregnancyColumnIndex() != DataTable::COLUMN_IS_MISSING){ _checkPregnancyStateValidity(); } _determineFoundingGroups(); bool sortFieldPresent = false; if(sortField != std::string("") && sortField != pedigreeTable.labels.DOBField){ // Check to see if the field actually exists in the data table if(pedigreeTable.columnExists(sortField)){ _computeWidths(sortField); sortFieldPresent = true; }else{ Warning("PedigreeSet::addPedigreesFromDataTable()", "Field '%s' specified for sorting the siblings does not exist in the Pedigree Table. Default ordering will be used.", sortField.c_str() ); } } if(!sortFieldPresent){ if(dobPresent){ //std::cout << "Siblings are ordered by DOB." << std::endl; _computeWidths(pedigreeTable.labels.DOBField,true); DrawingMetrics::setDisplayBirthOrder(true); }else{ //std::cout << "Default ordering of siblings." << std::endl; _computeWidths(std::string("")); } } //std::cout << vt100::startBlue << "┗ End of addPedigreesFromDataTable ┛" << vt100::stopColor << std::endl; }