void ChaosPlot::startDraw() { /** * Begins the drawing of a graph by setting up the buffers, drawing * the graphing rectangle, and placing a title on the graph. */ // update the sizes this->GetSize(&width, &height); graph_width = width - side_gutter_size; graph_height = height - bottom_gutter_size - top_gutter_size; if(dc) delete dc; dc = new wxClientDC(this); // Initialize the buffers bmp = new wxBitmap(); bmp->SetHeight(height); bmp->SetWidth(width); buffer = new wxBufferedDC(dc, *bmp); // Update drawing area int txt_width, txt_height; buffer->GetTextExtent(graph_title, &txt_width, &txt_height); top_gutter_size = 2*txt_height + 5; // Return plots are graphed in a square window if( square ) { if ( graph_width > graph_height ) { graph_width = graph_height; } else { graph_height = graph_width; } side_gutter_size = width/2 - graph_width/2; } // Clear data and draw our rectangle wxPen axisPen(*wxLIGHT_GREY, 1); buffer->SetPen(axisPen); buffer->SetBackground(dc->GetBackground()); buffer->Clear(); buffer->DrawRectangle(side_gutter_size, top_gutter_size, graph_width, graph_height + 1); // Draw our graph title buffer->DrawText(graph_title, (width/2) - (txt_width/2), 2); buffer->GetTextExtent(graph_subtitle, &txt_width, &txt_height); buffer->DrawText(graph_subtitle, (width/2) - (txt_width/2), 4+txt_height); }
void ChaosPlot::drawXAxis(float bottom, float top, float interval) { /** * Draws the X-Axis on the graph using the specified minimum and maximum * values as well as the interval. * * Uses integers as axis labels unless the interval is small, then uses * floats out to 1 decimal place. * * Also draws lines across the graph at the label values */ wxString buf; wxPen axisPen(*wxLIGHT_GREY, 1); buffer->SetPen(axisPen); float scale = graph_width/fabs(top - bottom); int num_labels = (int)(fabs(top - bottom)/fabs(interval)); for(int i = 0; i <= num_labels; i++ ) { if(fabs(int(interval) - interval) > .05 && abs(int(interval)) < 2.0) { buf = wxString::Format(wxT("%.2f"),(bottom + i*interval)); } else { buf = wxString::Format(wxT("%d"),int(bottom + i*interval)); } int x = (int)(scale*i*fabs(interval) + side_gutter_size); int y = (int)(graph_height + top_gutter_size); buffer->DrawText(buf, x-15, y+5); buffer->DrawLine(x, y+5, x, top_gutter_size); } }
wxBitmap BacklashGraph::CreateGraph(int bmpWidth, int bmpHeight) { wxMemoryDC dc; wxBitmap bmp(bmpWidth, bmpHeight, -1); wxPen axisPen("BLACK", 3, wxCROSS_HATCH); wxPen redPen("RED", 3, wxSOLID); wxPen bluePen("BLUE", 3, wxSOLID); wxBrush redBrush("RED", wxSOLID); wxBrush blueBrush("BLUE", wxSOLID); //double fakeNorthPoints[] = //{152.04, 164.77, 176.34, 188.5, 200.25, 212.36, 224.21, 236.89, 248.62, 260.25, 271.34, 283.54, 294.79, 307.56, 319.22, 330.87, 343.37, 355.75, 367.52, 379.7, 391.22, 403.89, 415.34, 427.09, 439.41, 450.36, 462.6}; //double fakeSouthPoints[] = //{474.84, 474.9, 464.01, 451.83, 438.08, 426, 414.68, 401.15, 390.39, 377.22, 366.17, 353.45, 340.75, 328.31, 316.93, 304.55, 292.42, 280.45, 269.03, 255.02, 243.76, 231.53, 219.43, 207.35, 195.22, 183.06, 169.47}; //std::vector <double> northSteps(fakeNorthPoints, fakeNorthPoints + 27); //std::vector <double> southSteps(fakeSouthPoints, fakeSouthPoints + 27); std::vector <double> northSteps = m_BLT->GetNorthSteps(); std::vector <double> southSteps = m_BLT->GetSouthSteps(); double xScaleFactor; double yScaleFactor; int xOrigin; int yOrigin; int ptRadius; int graphWindowWidth; int graphWindowHeight; int numNorth; double northInc; int numSouth; // Find the max excursion from the origin in order to scale the points to fit the bitmap double maxDec = -9999.0; double minDec = 9999.0; for (std::vector<double>::const_iterator it = northSteps.begin(); it != northSteps.end(); ++it) { maxDec = wxMax(maxDec, *it); minDec = wxMin(minDec, *it); } for (std::vector<double>::const_iterator it = southSteps.begin(); it != southSteps.end(); ++it) { maxDec = wxMax(maxDec, *it); minDec = wxMin(minDec, *it); } graphWindowWidth = bmpWidth; graphWindowHeight = 0.7 * bmpHeight; yScaleFactor = (graphWindowHeight) / (maxDec - minDec + 1); xScaleFactor = (graphWindowWidth) / (northSteps.size() + southSteps.size()); // Since we get mount coordinates, north steps will always be in ascending order numNorth = northSteps.size(); northInc = (northSteps.at(numNorth - 1) - northSteps.at(0)) / numNorth; numSouth = southSteps.size(); // Should be same as numNorth but be careful dc.SelectObject(bmp); dc.SetBackground(*wxLIGHT_GREY_BRUSH); dc.SetFont(wxFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)); dc.Clear(); // Bottom and top labels dc.SetTextForeground("BLUE"); dc.DrawText(_("Ideal"), 0.7 * graphWindowWidth, bmpHeight - 25); dc.SetTextForeground("RED"); dc.DrawText(_("Measured"), 0.2 * graphWindowWidth, bmpHeight - 25); dc.DrawText(_("North"), 0.1 * graphWindowWidth, 10); dc.DrawText(_("South"), 0.8 * graphWindowWidth, 10); // Draw the axes dc.SetPen(axisPen); xOrigin = graphWindowWidth / 2; yOrigin = graphWindowHeight + 40; // Leave room at the top for labels and such dc.DrawLine(0, yOrigin, graphWindowWidth, yOrigin); // x dc.DrawLine(xOrigin, yOrigin, xOrigin, 0); // y // Draw the north steps dc.SetPen(redPen); dc.SetBrush(redBrush); ptRadius = 2; for (int i = 0; i < numNorth; i++) { wxPoint where = wxPoint(i * xScaleFactor, round(yOrigin - (northSteps.at(i) - minDec) * yScaleFactor)); dc.DrawCircle(wxPoint(i * xScaleFactor, round(yOrigin - (northSteps.at(i) - minDec) * yScaleFactor)), ptRadius); } // Draw the south steps for (int i = 0; i < numSouth; i++) { dc.DrawCircle(wxPoint((i + numNorth) * xScaleFactor, round(yOrigin - (southSteps.at(i) - minDec) * yScaleFactor)), ptRadius); } // Now show an ideal south recovery line dc.SetPen(bluePen); dc.SetBrush(blueBrush); double peakSouth = southSteps.at(0); for (int i = 1; i <= numNorth; i++) { wxPoint where = wxPoint((i + numNorth)* xScaleFactor, round(yOrigin - (peakSouth - i * northInc - minDec) * yScaleFactor)); dc.DrawCircle(where, ptRadius); } dc.SelectObject(wxNullBitmap); return bmp; }
void DlgHisto::OnPaint() { CPaintDC dc(this); // device context for painting CDemoDoc* pDoc = (CDemoDoc*) ((CMainFrame*)AfxGetMainWnd())->GetActiveFrame()->GetActiveDocument(); RECT r; GetClientRect(&r); CPen gridPen(PS_DOT,1,::GetSysColor(COLOR_APPWORKSPACE)); CPen* pOldPen = dc.SelectObject(&gridPen); for (int gx=9+32;gx<265;gx+=32){ dc.MoveTo(gx,40); dc.LineTo(gx,r.bottom - 6); } for (int gy=0;gy<(r.bottom - 40);gy+=((r.bottom - 40)/10)){ dc.MoveTo(8,r.bottom - 9 - gy); dc.LineTo(268,r.bottom - 9 - gy); } dc.SelectObject(pOldPen); CPen axisPen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW)); pOldPen = dc.SelectObject(&axisPen); dc.MoveTo(9, 38); dc.LineTo(9, r.bottom - 9); dc.LineTo(266, r.bottom - 9); dc.LineTo(266, 38); dc.SelectObject(pOldPen); if (pDoc && pDoc->image) { if (pDoc->m_hmax){ int ybase = r.bottom-10; if (m_logen){ float yratio = (r.bottom - r.top - 50)/(float)log10((float)(pDoc->m_hmax+1)); if (m_ren){ CPen redPen(PS_SOLID, 1, RGB(222, 0, 0)); pOldPen = dc.SelectObject(&redPen); dc.MoveTo(10, (int)(ybase-log10((float)(1+pDoc->m_hr[0]))*yratio)); for (int x=1; x<256; x++) dc.LineTo(x+10, (int)(ybase-log10((float)(1+pDoc->m_hr[x]))*yratio)); } if (m_gen){ CPen greenPen(PS_SOLID, 1, RGB(0, 222, 0)); pOldPen = dc.SelectObject(&greenPen); dc.MoveTo(10, (int)(ybase-log10((float)(1+pDoc->m_hg[0]))*yratio)); for (int x=1; x<256; x++) dc.LineTo(x+10, (int)(ybase-log10((float)(1+pDoc->m_hg[x]))*yratio)); } if (m_ben){ CPen bluePen(PS_SOLID, 1, RGB(0, 0, 222)); pOldPen = dc.SelectObject(&bluePen); dc.MoveTo(10, (int)(ybase-log10((float)(1+pDoc->m_hb[0]))*yratio)); for (int x=1; x<256; x++) dc.LineTo(x+10, (int)(ybase-log10((float)(1+pDoc->m_hb[x]))*yratio)); } if (m_grayen){ CPen grayPen(PS_SOLID, 1, RGB(64, 64, 64)); pOldPen = dc.SelectObject(&grayPen); dc.MoveTo(10, (int)(ybase-log10((float)(1+pDoc->m_hgray[0]))*yratio)); for (int x=1; x<256; x++) dc.LineTo(x+10, (int)(ybase-log10((float)(1+pDoc->m_hgray[x]))*yratio)); } dc.SelectObject(pOldPen); } else { float yratio = (r.bottom - r.top - 50)/(float)pDoc->m_hmax; if (m_ren){ CPen redPen(PS_SOLID, 1, RGB(222, 0, 0)); pOldPen = dc.SelectObject(&redPen); dc.MoveTo(10, (int)(ybase-pDoc->m_hr[0]*yratio)); for (int x=1; x<256; x++) dc.LineTo(x+10, (int)(ybase-pDoc->m_hr[x]*yratio)); } if (m_gen){ CPen greenPen(PS_SOLID, 1, RGB(0, 222, 0)); pOldPen = dc.SelectObject(&greenPen); dc.MoveTo(10, (int)(ybase-pDoc->m_hg[0]*yratio)); for (int x=1; x<256; x++) dc.LineTo(x+10, (int)(ybase-pDoc->m_hg[x]*yratio)); } if (m_ben){ CPen bluePen(PS_SOLID, 1, RGB(0, 0, 222)); pOldPen = dc.SelectObject(&bluePen); dc.MoveTo(10, (int)(ybase-pDoc->m_hb[0]*yratio)); for (int x=1; x<256; x++) dc.LineTo(x+10, (int)(ybase-pDoc->m_hb[x]*yratio)); } if (m_grayen){ CPen grayPen(PS_SOLID, 1, RGB(64, 64, 64)); pOldPen = dc.SelectObject(&grayPen); dc.MoveTo(10, (int)(ybase-pDoc->m_hgray[0]*yratio)); for (int x=1; x<256; x++) dc.LineTo(x+10, (int)(ybase-pDoc->m_hgray[x]*yratio)); } dc.SelectObject(pOldPen); } } else { pDoc->m_hmax=pDoc->GetImage()->Histogram(pDoc->m_hr,pDoc->m_hg,pDoc->m_hb,pDoc->m_hgray); if (pDoc->m_hmax) Invalidate(); } } }
// Build the calibration "step" graph which will appear on the lefthand side of the panels wxBitmap CalReviewDialog::CreateGraph(bool AO) { wxMemoryDC memDC; wxBitmap bmp(CALREVIEW_BITMAP_SIZE, CALREVIEW_BITMAP_SIZE, -1); wxPen axisPen("GREY", 3, wxCROSS_HATCH); wxColour raColor = pFrame->pGraphLog->GetRaOrDxColor(); wxColour decColor = pFrame->pGraphLog->GetDecOrDyColor(); wxPen raPen(raColor, 3, wxSOLID); wxPen decPen(decColor, 3, wxSOLID); wxBrush raBrush(raColor, wxSOLID); wxBrush decBrush(decColor, wxSOLID); CalibrationDetails calDetails; double scaleFactor; int ptRadius; if (!pSecondaryMount) { pMount->GetCalibrationDetails(&calDetails); // Normal case, no AO } else { if (AO) { pMount->GetCalibrationDetails(&calDetails); // AO tab, use AO details } else { pSecondaryMount->GetCalibrationDetails(&calDetails); // Mount tab, use mount details } } // Find the max excursion from the origin in order to scale the points to fit the bitmap double biggestVal = -100.0; for (std::vector<wxRealPoint>::const_iterator it = calDetails.raSteps.begin(); it != calDetails.raSteps.end(); ++it) { biggestVal = wxMax(biggestVal, fabs(it->x)); biggestVal = wxMax(biggestVal, fabs(it->y)); } for (std::vector<wxRealPoint>::const_iterator it = calDetails.decSteps.begin(); it != calDetails.decSteps.end(); ++it) { biggestVal = wxMax(biggestVal, fabs(it->x)); biggestVal = wxMax(biggestVal, fabs(it->y)); } if (biggestVal > 0.0) scaleFactor = ((CALREVIEW_BITMAP_SIZE - 5) / 2) / biggestVal; // Leave room for circular point else scaleFactor = 1.0; memDC.SelectObject(bmp); memDC.SetBackground(*wxBLACK_BRUSH); memDC.Clear(); memDC.SetPen(axisPen); // Draw the axes memDC.SetDeviceOrigin(wxCoord(CALREVIEW_BITMAP_SIZE / 2), wxCoord(CALREVIEW_BITMAP_SIZE / 2)); memDC.DrawLine(-CALREVIEW_BITMAP_SIZE / 2, 0, CALREVIEW_BITMAP_SIZE / 2, 0); // x memDC.DrawLine(0, -CALREVIEW_BITMAP_SIZE / 2, 0, CALREVIEW_BITMAP_SIZE / 2); // y if (calDetails.raStepCount > 0) { // Draw the RA data memDC.SetPen(raPen); memDC.SetBrush(raBrush); ptRadius = 2; // Scale the points, then plot them individually for (int i = 0; i < (int) calDetails.raSteps.size(); i++) { if (i == calDetails.raStepCount + 2) // Valid even for "single-step" calibration { memDC.SetPen(wxPen(raColor, 1)); // 1-pixel-thick outline memDC.SetBrush(wxNullBrush); // Outline only for "return" data points ptRadius = 3; } memDC.DrawCircle(IntPoint(calDetails.raSteps.at(i), scaleFactor), ptRadius); } // Show the line PHD2 will use for the rate memDC.SetPen(raPen); if ((int)calDetails.raSteps.size() > calDetails.raStepCount) // New calib, includes return values memDC.DrawLine(IntPoint(calDetails.raSteps.at(0), scaleFactor), IntPoint(calDetails.raSteps.at(calDetails.raStepCount), scaleFactor)); else memDC.DrawLine(IntPoint(calDetails.raSteps.at(0), scaleFactor), IntPoint(calDetails.raSteps.at(calDetails.raStepCount - 1), scaleFactor)); } // Handle the Dec data memDC.SetPen(decPen); memDC.SetBrush(decBrush); ptRadius = 2; if (calDetails.decStepCount > 0) { for (int i = 0; i < (int) calDetails.decSteps.size(); i++) { if (i == calDetails.decStepCount + 2) { memDC.SetPen(wxPen(decColor, 1)); // 1-pixel-thick outline memDC.SetBrush(wxNullBrush); // Outline only for "return" data points ptRadius = 3; } memDC.DrawCircle(IntPoint(calDetails.decSteps.at(i), scaleFactor), ptRadius); } // Show the line PHD2 will use for the rate memDC.SetPen(decPen); if ((int)calDetails.decSteps.size() > calDetails.decStepCount) // New calib, includes return values memDC.DrawLine(IntPoint(calDetails.decSteps.at(0), scaleFactor), IntPoint(calDetails.decSteps.at(calDetails.decStepCount), scaleFactor)); else memDC.DrawLine(IntPoint(calDetails.decSteps.at(0), scaleFactor), IntPoint(calDetails.decSteps.at(calDetails.decStepCount - 1), scaleFactor)); } memDC.SelectObject(wxNullBitmap); return bmp; }
void ExoplanetsDialog::populateDiagramsList() { Q_ASSERT(ui->comboAxisX); Q_ASSERT(ui->comboAxisY); QColor axisColor(Qt::white); QPen axisPen(axisColor, 1); ui->customPlot->setBackground(QBrush(QColor(86, 87, 90))); ui->customPlot->xAxis->setLabelColor(axisColor); ui->customPlot->xAxis->setTickLabelColor(axisColor); ui->customPlot->xAxis->setBasePen(axisPen); ui->customPlot->xAxis->setTickPen(axisPen); ui->customPlot->xAxis->setSubTickPen(axisPen); ui->customPlot->yAxis->setLabelColor(axisColor); ui->customPlot->yAxis->setTickLabelColor(axisColor); ui->customPlot->yAxis->setBasePen(axisPen); ui->customPlot->yAxis->setTickPen(axisPen); ui->customPlot->yAxis->setSubTickPen(axisPen); QComboBox* axisX = ui->comboAxisX; QComboBox* axisY = ui->comboAxisY; //Save the current selection to be restored later axisX->blockSignals(true); axisY->blockSignals(true); int indexX = axisX->currentIndex(); int indexY = axisY->currentIndex(); QVariant selectedAxisX = axisX->itemData(indexX); QVariant selectedAxisY = axisY->itemData(indexY); axisX->clear(); axisY->clear(); QList<axisPair> axis; axis.append(qMakePair(q_("Orbital Eccentricity"), 0)); axis.append(qMakePair(q_("Orbit Semi-Major Axis, AU"), 1)); axis.append(qMakePair(q_("Planetary Mass, Mjup"), 2)); axis.append(qMakePair(q_("Planetary Radius, Rjup"), 3)); axis.append(qMakePair(q_("Orbital Period, days"), 4)); axis.append(qMakePair(q_("Angular Distance, arcsec"), 5)); axis.append(qMakePair(q_("Effective temperature of host star, K"), 6)); axis.append(qMakePair(q_("Year of Discovery"), 7)); axis.append(qMakePair(q_("Metallicity of host star"), 8)); axis.append(qMakePair(q_("V magnitude of host star, mag"), 9)); axis.append(qMakePair(q_("RA (J2000) of star, deg"), 10)); axis.append(qMakePair(q_("Dec (J2000) of star, deg"), 11)); axis.append(qMakePair(q_("Distance to star, pc"), 12)); axis.append(qMakePair(q_("Mass of host star, Msol"), 13)); axis.append(qMakePair(q_("Radius of host star, Rsol"), 14)); for(int i=0; i<axis.size(); ++i) { axisX->addItem(axis.at(i).first, axis.at(i).second); axisY->addItem(axis.at(i).first, axis.at(i).second); } //Restore the selection indexX = axisX->findData(selectedAxisX, Qt::UserRole, Qt::MatchCaseSensitive); if (indexX<0) indexX = 1; indexY = axisY->findData(selectedAxisY, Qt::UserRole, Qt::MatchCaseSensitive); if (indexY<0) indexY = 0; axisX->setCurrentIndex(indexX); axisY->setCurrentIndex(indexY); axisX->blockSignals(false); axisY->blockSignals(false); }