MainWindow::MainWindow( QWidget* parent ) : QWidget( parent ), m_model(0) { setupUi( this ); QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); m_chart = new Chart(); chartLayout->addWidget( m_chart ); // Set up the data initializeDataModel(); // Set up the diagram m_plotter = new Plotter(); // Register the data model at the diagram m_plotter->setModel( m_model ); // Add axes to the diagram CartesianAxis *xAxis = new CartesianAxis( m_plotter ); CartesianAxis *xAxis2 = new CartesianAxis( m_plotter ); CartesianAxis *yAxis = new CartesianAxis ( m_plotter ); CartesianAxis *yAxis2 = new CartesianAxis ( m_plotter ); xAxis->setPosition ( KDChart::CartesianAxis::Bottom ); xAxis2->setPosition( KDChart::CartesianAxis::Top ); yAxis->setPosition ( KDChart::CartesianAxis::Left ); yAxis2->setPosition( KDChart::CartesianAxis::Right ); m_plotter->addAxis( xAxis ); m_plotter->addAxis( xAxis2 ); m_plotter->addAxis( yAxis ); m_plotter->addAxis( yAxis2 ); connect( threeDEnabled, SIGNAL( toggled(bool) ), this, SLOT( setMarkerAttributes() ) ); m_chart->coordinatePlane()->replaceDiagram( m_plotter ); m_chart->setGlobalLeading( 20, 20, 20, 20 ); setMarkerAttributes(); }
void ChartWidget::setModel(ChartModel* model) { auto* coordinatePlane = dynamic_cast<CartesianCoordinatePlane*>(m_chart->coordinatePlane()); Q_ASSERT(coordinatePlane); foreach (auto diagram, coordinatePlane->diagrams()) { coordinatePlane->takeDiagram(diagram); delete diagram; } { auto totalPlotter = new Plotter(this); totalPlotter->setAntiAliasing(true); auto totalProxy = new ChartProxy(true, this); totalProxy->setSourceModel(model); totalPlotter->setModel(totalProxy); totalPlotter->setType(Plotter::Stacked); KColorScheme scheme(QPalette::Active, KColorScheme::Window); const QPen foreground(scheme.foreground().color()); auto bottomAxis = new TimeAxis(totalPlotter); auto axisTextAttributes = bottomAxis->textAttributes(); axisTextAttributes.setPen(foreground); bottomAxis->setTextAttributes(axisTextAttributes); auto axisTitleTextAttributes = bottomAxis->titleTextAttributes(); axisTitleTextAttributes.setPen(foreground); bottomAxis->setTitleTextAttributes(axisTitleTextAttributes); bottomAxis->setTitleText(model->headerData(0).toString()); bottomAxis->setPosition(CartesianAxis::Bottom); totalPlotter->addAxis(bottomAxis); CartesianAxis* rightAxis = model->type() == ChartModel::Allocations ? new CartesianAxis(totalPlotter) : new SizeAxis(totalPlotter); rightAxis->setTextAttributes(axisTextAttributes); rightAxis->setTitleTextAttributes(axisTitleTextAttributes); rightAxis->setTitleText(model->headerData(1).toString()); rightAxis->setPosition(CartesianAxis::Right); totalPlotter->addAxis(rightAxis); coordinatePlane->addDiagram(totalPlotter); } { auto plotter = new Plotter(this); plotter->setAntiAliasing(true); plotter->setType(Plotter::Stacked); auto proxy = new ChartProxy(false, this); proxy->setSourceModel(model); plotter->setModel(proxy); coordinatePlane->addDiagram(plotter); } }
MainWindow::MainWindow( QWidget* parent ) : QWidget( parent ) { setupUi( this ); QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); m_chart = new Chart(); m_chart->setGlobalLeading( 20, 20, 20, 20 ); chartLayout->addWidget( m_chart ); // Initialize the model, and fill it with data const int rowCount = 8; const int columnCount = 3; m_model = new QStandardItemModel(rowCount, columnCount, this); m_model->setHeaderData(0, Qt::Horizontal, tr("Product A")); m_model->setHeaderData(1, Qt::Horizontal, tr("Product B")); m_model->setHeaderData(2, Qt::Horizontal, tr("Product C")); openFile(":/Charts/qtdata.cht"); // Set up the diagram m_lines = new LineDiagram(); // Register the data model at the diagram m_lines->setModel( m_model ); // Add axes to the diagram CartesianAxis *xAxis = new CartesianAxis( m_lines ); CartesianAxis *yAxis = new CartesianAxis ( m_lines ); xAxis->setPosition ( KDChart::CartesianAxis::Bottom ); yAxis->setPosition ( KDChart::CartesianAxis::Left ); m_lines->addAxis( xAxis ); m_lines->addAxis( yAxis ); // Make the lines thicker for( int iColumn = 0; iColumn < columnCount; ++iColumn ){ QPen linePen( m_lines->pen( iColumn ) ); linePen.setWidth( 3 ); m_lines->setPen( iColumn, linePen ); } // Register the diagram at the coordinate plane m_chart->coordinatePlane()->replaceDiagram( m_lines ); // Add a legend Legend* legend = new Legend( m_lines, m_chart ); legend->setPosition( Position::South ); legend->setAlignment( Qt::AlignCenter ); legend->setShowLines( true ); legend->setTitleText(""); legend->setOrientation( Qt::Horizontal ); legend->addDiagram( m_lines ); m_chart->addLegend( legend ); }
MainWindow::MainWindow( QWidget* parent ) : QWidget( parent ) { setupUi( this ); m_curColumn = -1; m_curOpacity = 0; QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); m_chart = new Chart(); chartLayout->addWidget( m_chart ); m_model.loadFromCSV( ":/data" ); // Set up the diagram m_lines = new LineDiagram( this ); m_lines->setModel( &m_model ); CartesianAxis* xAxis = new CartesianAxis( m_lines ); CartesianAxis* yAxis = new CartesianAxis( m_lines ); xAxis->setPosition( KChart::CartesianAxis::Bottom ); yAxis->setPosition( KChart::CartesianAxis::Left ); m_lines->addAxis( xAxis ); m_lines->addAxis( yAxis ); m_chart->coordinatePlane()->replaceDiagram( m_lines ); m_chart->setGlobalLeading( 20, 20, 20, 20 ); // Instantiate the timer QTimer* timer = new QTimer( this ); connect( timer, SIGNAL( timeout() ), this, SLOT( slot_timerFired() ) ); timer->start( 30 ); //Change the cursor to IBeamCursor inside Chart widget. m_chart->setCursor( Qt::IBeamCursor ); //Install event filter on Chart to get the mouse position m_chart->installEventFilter( this ); }
MainWindow::MainWindow( QWidget *parent ) : QWidget( parent ) , m_chart( new Chart() ) , m_diagram( m_chart ) { setupUi( this ); m_HLCModel.loadFromCSV( ":/HLC" ); m_OHLCModel.loadFromCSV( ":/OHLC" ); m_diagram.setType( StockDiagram::HighLowClose ); m_diagram.setModel( &m_HLCModel ); m_chart->coordinatePlane()->replaceDiagram( &m_diagram ); KDChart::Legend* legend = new KDChart::Legend( &m_diagram, m_chart ); m_chart->addLegend( legend ); QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); chartLayout->addWidget( m_chart ); // Abscissa CartesianAxis *leftAxis = new CartesianAxis( &m_diagram ); // Ordinate CartesianAxis *bottomAxis = new CartesianAxis( &m_diagram ); leftAxis->setPosition( CartesianAxis::Left ); TextAttributes attributes = bottomAxis->textAttributes(); attributes.setRotation( 90 ); attributes.setFontSize( Measure( 7.0, KDChartEnums::MeasureCalculationModeAbsolute ) ); bottomAxis->setTextAttributes( attributes ); bottomAxis->setPosition( CartesianAxis::Bottom ); m_diagram.addAxis( leftAxis ); m_diagram.addAxis( bottomAxis ); m_diagram.addAxis( bottomAxis ); applyColor( QColor( "chartreuse" ) ); const bool connected = connect( colorChooser, SIGNAL( clicked() ), SLOT( chooseColor() ) ); Q_ASSERT( connected ); Q_UNUSED( connected ); // Initialize all values for the stock chart to sane defaults initValues(); }
MainWindow::MainWindow( QWidget* parent ) : QWidget( parent ) { setupUi( this ); QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); m_chart = new Chart(); m_chart->setGlobalLeading( 10, 10, 10, 10 ); chartLayout->addWidget( m_chart ); hSBar->setVisible( false ); vSBar->setVisible( false ); m_model.loadFromCSV( ":/data" ); // Set up the diagram m_lines = new BarDiagram(); m_lines->setModel( &m_model ); // create and position axis CartesianAxis *topAxis = new CartesianAxis( m_lines ); CartesianAxis *leftAxis = new CartesianAxis ( m_lines ); RulerAttributes rulerAttr = topAxis->rulerAttributes(); rulerAttr.setTickMarkPen( 0.9999999, QPen( Qt::red ) ); rulerAttr.setTickMarkPen( 2.0, QPen( Qt::green ) ); rulerAttr.setTickMarkPen( 3.0, QPen( Qt::blue ) ); rulerAttr.setShowMinorTickMarks(true); //rulerAttr.setShowMajorTickMarks(false); topAxis->setRulerAttributes( rulerAttr ); CartesianAxis *rightAxis = new CartesianAxis ( m_lines ); CartesianAxis *bottomAxis = new CartesianAxis ( m_lines ); topAxis->setPosition ( CartesianAxis::Top ); leftAxis->setPosition ( CartesianAxis::Left ); rightAxis->setPosition ( CartesianAxis::Right ); bottomAxis->setPosition ( CartesianAxis::Bottom ); // set the margin that should be used between the displayed labels and the ticks to zero #if 0 RulerAttributes ra = bottomAxis->rulerAttributes(); ra.setLabelMargin(0); bottomAxis->setRulerAttributes( ra ); #endif // show a red frame around the bottom axis #if 0 FrameAttributes fa( bottomAxis->frameAttributes() ); fa.setPen( QPen(QBrush(QColor("#ff0000")),1.0) ); fa.setVisible( true ); bottomAxis->setFrameAttributes( fa ); #endif // set axis titles topAxis->setTitleText ( "Abscissa color configured top position" ); leftAxis->setTitleText ( "left Ordinate: fonts configured" ); rightAxis->setTitleText ( "right Ordinate: default settings" ); bottomAxis->setTitleText ( "Abscissa Bottom" ); topAxis->setTitleSize(1.1); topAxis->setTitleSpace(.4); // configure titles text attributes TextAttributes taTop ( topAxis->titleTextAttributes () ); taTop.setPen( QPen( Qt::red ) ); topAxis->setTitleTextAttributes ( taTop ); TextAttributes taLeft ( leftAxis->titleTextAttributes () ); taLeft.setRotation( 180 ); Measure me( taLeft.fontSize() ); me.setValue( me.value() * 0.8 ); taLeft.setFontSize( me ); // Set the following to 1, to hide the left axis title // - no matter if a title text is set or not #if 0 taLeft.setVisible( false ); #endif leftAxis->setTitleTextAttributes ( taLeft ); TextAttributes taBottom ( bottomAxis->titleTextAttributes () ); taBottom.setPen( QPen( Qt::blue ) ); bottomAxis->setTitleTextAttributes ( taBottom ); // configure labels text attributes TextAttributes taLabels( topAxis->textAttributes() ); taLabels.setPen( QPen( Qt::darkGreen ) ); taLabels.setRotation( 90 ); topAxis->setTextAttributes( taLabels ); leftAxis->setTextAttributes( taLabels ); bottomAxis->setTextAttributes( taLabels ); // Set the following to 0, to see the default Abscissa labels // (== X headers, as read from the data file) #if 1 // configure labels and their shortened versions QStringList daysOfWeek; daysOfWeek << "M O N D A Y" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" ; topAxis->setLabels( daysOfWeek ); QStringList shortDays; shortDays << "MON" << "Tue" << "Wed" << "Thu" << "Fri"; topAxis->setShortLabels( shortDays ); QStringList bottomLabels; bottomLabels << "Team A" << "Team B" << "Team C"; bottomAxis->setLabels( bottomLabels ); QStringList shortBottomLabels; shortBottomLabels << "A" << "B"; bottomAxis->setShortLabels( shortBottomLabels ); #endif // add axis m_lines->addAxis( topAxis ); m_lines->addAxis( leftAxis ); m_lines->addAxis( rightAxis ); m_lines->addAxis( bottomAxis ); // assign diagram to chart view m_chart->coordinatePlane()->replaceDiagram( m_lines ); }
void KReportChartView::drawPivotChart(const PivotGrid &grid, const MyMoneyReport &config, int numberColumns, const QStringList& columnHeadings, const QList<ERowType>& rowTypeList, const QStringList& columnTypeHeaderList) { //set the number of columns setNumColumns(numberColumns); //set skipZero m_skipZero = config.isSkippingZero(); //remove existing headers while (headerFooters().count() > 0) { HeaderFooter* delHeader = headerFooters().at(0); takeHeaderFooter(delHeader); delete delHeader; } //make sure the model is clear m_model.removeColumns(0, m_model.columnCount()); m_model.removeRows(0, m_model.rowCount()); //set the new header HeaderFooter* header = new HeaderFooter(this); header->setText(config.name()); header->setType(HeaderFooter::Header); header->setPosition(Position::North); TextAttributes headerTextAttr(header->textAttributes()); headerTextAttr.setPen(m_foregroundBrush.color()); header->setTextAttributes(headerTextAttr); addHeaderFooter(header); // whether to limit the chart to use series totals only. Used for reports which only // show one dimension (pie). setSeriesTotals(false); // whether series (rows) are accounts (true) or months (false). This causes a lot // of complexity in the charts. The problem is that circular reports work best with // an account in a COLUMN, while line/bar prefer it in a ROW. setAccountSeries(true); switch (config.chartType()) { case MyMoneyReport::eChartNone: case MyMoneyReport::eChartEnd: case MyMoneyReport::eChartLine: { KDChart::LineDiagram* diagram = new KDChart::LineDiagram; if (config.isSkippingZero()) { LineAttributes attributes = diagram->lineAttributes(); attributes.setMissingValuesPolicy(LineAttributes::MissingValuesAreBridged); diagram->setLineAttributes(attributes); } CartesianCoordinatePlane* cartesianPlane = new CartesianCoordinatePlane; replaceCoordinatePlane(cartesianPlane); coordinatePlane()->replaceDiagram(diagram); break; } case MyMoneyReport::eChartBar: { KDChart::BarDiagram* diagram = new KDChart::BarDiagram; CartesianCoordinatePlane* cartesianPlane = new CartesianCoordinatePlane; replaceCoordinatePlane(cartesianPlane); coordinatePlane()->replaceDiagram(diagram); break; } case MyMoneyReport::eChartStackedBar: { KDChart::BarDiagram* diagram = new KDChart::BarDiagram; CartesianCoordinatePlane* cartesianPlane = new CartesianCoordinatePlane; replaceCoordinatePlane(cartesianPlane); diagram->setType(BarDiagram::Stacked); coordinatePlane()->replaceDiagram(diagram); break; } case MyMoneyReport::eChartPie: { KDChart::PieDiagram* diagram = new KDChart::PieDiagram; PolarCoordinatePlane* polarPlane = new PolarCoordinatePlane; replaceCoordinatePlane(polarPlane); coordinatePlane()->replaceDiagram(diagram); setAccountSeries(false); setSeriesTotals(true); break; } case MyMoneyReport::eChartRing: { KDChart::RingDiagram* diagram = new KDChart::RingDiagram; PolarCoordinatePlane* polarPlane = new PolarCoordinatePlane; replaceCoordinatePlane(polarPlane); polarPlane->replaceDiagram(diagram); //chartView.params()->setRelativeRingThickness( true ); setAccountSeries(false); break; } } //get the diagram for later use AbstractDiagram* planeDiagram = coordinatePlane()->diagram(); //set grid attributes GridAttributes gridAttr(coordinatePlane()->globalGridAttributes()); gridAttr.setGridVisible(config.isChartGridLines()); coordinatePlane()->setGlobalGridAttributes(gridAttr); //the palette - we set it here because it is a property of the diagram switch (KMyMoneySettings::chartsPalette()) { case 0: planeDiagram->useDefaultColors(); break; case 1: planeDiagram->useRainbowColors(); break; case 2: default: planeDiagram->useSubduedColors(); break; } //the legend will be used later Legend* legend = new Legend(planeDiagram, this); legend->setTitleText(i18nc("Chart legend title", "Legend")); //set up the axes for cartesian diagrams if (config.chartType() == MyMoneyReport::eChartLine || config.chartType() == MyMoneyReport::eChartBar || config.chartType() == MyMoneyReport::eChartStackedBar) { //set x axis CartesianAxis *xAxis = new CartesianAxis(); xAxis->setPosition(CartesianAxis::Bottom); xAxis->setTitleText(i18n("Time")); TextAttributes xAxisTitleTextAttr(xAxis->titleTextAttributes()); xAxisTitleTextAttr.setMinimalFontSize(KGlobalSettings::generalFont().pointSize()); xAxisTitleTextAttr.setPen(m_foregroundBrush.color()); xAxis->setTitleTextAttributes(xAxisTitleTextAttr); TextAttributes xAxisTextAttr(xAxis->textAttributes()); xAxisTextAttr.setPen(m_foregroundBrush.color()); xAxis->setTextAttributes(xAxisTextAttr); RulerAttributes xAxisRulerAttr(xAxis->rulerAttributes()); xAxisRulerAttr.setTickMarkPen(m_foregroundBrush.color()); xAxisRulerAttr.setShowRulerLine(true); xAxis->setRulerAttributes(xAxisRulerAttr); // Set up X axis labels (ie "abscissa" to use the technical term) QStringList abscissaNames; if (accountSeries()) { // if not, we will set these up while putting in the chart values. int column = 1; while (column < numColumns()) { abscissaNames += QString(columnHeadings[column++]).replace(" ", " "); } xAxis->setLabels(abscissaNames); } //set y axis KBalanceAxis *yAxis = new KBalanceAxis(); yAxis->setPosition(CartesianAxis::Left); // TODO // if the chart shows prices and no balance // the axis title should be 'Price' if (config.isIncludingPrice()) { yAxis->setTitleText(i18n("Price")); } else { yAxis->setTitleText(i18n("Balance")); } TextAttributes yAxisTitleTextAttr(yAxis->titleTextAttributes()); yAxisTitleTextAttr.setMinimalFontSize(KGlobalSettings::generalFont().pointSize()); yAxisTitleTextAttr.setPen(m_foregroundBrush.color()); yAxis->setTitleTextAttributes(yAxisTitleTextAttr); TextAttributes yAxisTextAttr(yAxis->textAttributes()); yAxisTextAttr.setPen(m_foregroundBrush.color()); yAxis->setTextAttributes(yAxisTextAttr); RulerAttributes yAxisRulerAttr(yAxis->rulerAttributes()); yAxisRulerAttr.setTickMarkPen(m_foregroundBrush.color()); yAxisRulerAttr.setShowRulerLine(true); yAxis->setRulerAttributes(yAxisRulerAttr); //add the axes to the corresponding diagram if (config.chartType() == MyMoneyReport::eChartLine) { KDChart::LineDiagram* lineDiagram = qobject_cast<LineDiagram*>(planeDiagram); lineDiagram->addAxis(xAxis); lineDiagram->addAxis(yAxis); } else if (config.chartType() == MyMoneyReport::eChartBar || config.chartType() == MyMoneyReport::eChartStackedBar) { KDChart::BarDiagram* barDiagram = qobject_cast<BarDiagram*>(planeDiagram); barDiagram->addAxis(xAxis); barDiagram->addAxis(yAxis); } } switch (config.detailLevel()) { case MyMoneyReport::eDetailNone: case MyMoneyReport::eDetailEnd: case MyMoneyReport::eDetailAll: { int rowNum = 0; // iterate over outer groups PivotGrid::const_iterator it_outergroup = grid.begin(); while (it_outergroup != grid.end()) { // iterate over inner groups PivotOuterGroup::const_iterator it_innergroup = (*it_outergroup).begin(); while (it_innergroup != (*it_outergroup).end()) { // // Rows // QString innergroupdata; PivotInnerGroup::const_iterator it_row = (*it_innergroup).begin(); while (it_row != (*it_innergroup).end()) { //Do not include investments accounts in the chart because they are merely container of stock and other accounts if (it_row.key().accountType() != MyMoneyAccount::Investment) { //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + it_row.key().name()); } else { legendText = QString(it_row.key().name()); } //set the cell value and tooltip rowNum = drawPivotRowSet(rowNum, it_row.value(), rowTypeList[i], legendText, 1, numColumns()); //set the legend text legend->setText(rowNum - 1, legendText); } } } ++it_row; } ++it_innergroup; } ++it_outergroup; } } break; case MyMoneyReport::eDetailTop: { int rowNum = 0; // iterate over outer groups PivotGrid::const_iterator it_outergroup = grid.begin(); while (it_outergroup != grid.end()) { // iterate over inner groups PivotOuterGroup::const_iterator it_innergroup = (*it_outergroup).begin(); while (it_innergroup != (*it_outergroup).end()) { //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + it_innergroup.key()); } else { legendText = QString(it_innergroup.key()); } //set the cell value and tooltip rowNum = drawPivotRowSet(rowNum, (*it_innergroup).m_total, rowTypeList[i], legendText, 1, numColumns()); //set the legend text legend->setText(rowNum - 1, legendText); } } ++it_innergroup; } ++it_outergroup; } } break; case MyMoneyReport::eDetailGroup: { int rowNum = 0; // iterate over outer groups PivotGrid::const_iterator it_outergroup = grid.begin(); while (it_outergroup != grid.end()) { //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + it_outergroup.key()); } else { legendText = QString(it_outergroup.key()); } //set the cell value and tooltip rowNum = drawPivotRowSet(rowNum, (*it_outergroup).m_total, rowTypeList[i], legendText, 1, numColumns()); //set the legend legend->setText(rowNum - 1, legendText); } } ++it_outergroup; } //if selected, show totals too if (config.isShowingRowTotals()) { //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + i18nc("Total balance", "Total")); } else { legendText = QString(i18nc("Total balance", "Total")); } //set the cell value rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, 1, numColumns()); //set the legend legend->setText(rowNum - 1, legendText); } } } } break; case MyMoneyReport::eDetailTotal: { int rowNum = 0; //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + i18nc("Total balance", "Total")); } else { legendText = QString(i18nc("Total balance", "Total")); } if (config.isMixedTime() && (rowTypeList[i] == eActual || rowTypeList[i] == eForecast)) { if (rowTypeList[i] == eActual) { rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, 1, config.currentDateColumn()); } else if (rowTypeList[i] == eForecast) { rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, config.currentDateColumn(), numColumns()); } else { rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, 1, numColumns()); } } else { //set cell value rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, 1, numColumns()); } //set legend text legend->setText(rowNum - 1, legendText); } } } break; } //assign model to the diagram planeDiagram->setModel(&m_model); //set the legend basic attributes //this is done after adding the legend because the values are overridden when adding the legend to the chart for (uint i = static_cast<uint>(KMyMoneyGlobalSettings::maximumLegendItems()); i < legend->datasetCount(); ++i) { legend->setDatasetHidden(i, true); } legend->setTitleText(i18nc("Chart lines legend", "Legend")); legend->setUseAutomaticMarkerSize(false); FrameAttributes legendFrameAttr(legend->frameAttributes()); legendFrameAttr.setPen(m_foregroundBrush.color()); // leave some space between the content and the frame legendFrameAttr.setPadding(2); legend->setFrameAttributes(legendFrameAttr); legend->setPosition(Position::East); legend->setTextAlignment(Qt::AlignLeft); legend->setLegendStyle(KDChart::Legend::MarkersAndLines); replaceLegend(legend); // set the text attributes after calling replaceLegend() otherwise fon sizes will get overwritten qreal generalFontSize = KGlobalSettings::generalFont().pointSizeF(); if (generalFontSize == -1) generalFontSize = 8; // this is a fallback if the fontsize was specified in pixels TextAttributes legendTextAttr(legend->textAttributes()); legendTextAttr.setPen(m_foregroundBrush.color()); legendTextAttr.setFontSize(KDChart::Measure(generalFontSize, KDChartEnums::MeasureCalculationModeAbsolute)); legend->setTextAttributes(legendTextAttr); TextAttributes legendTitleTextAttr(legend->titleTextAttributes()); legendTitleTextAttr.setPen(m_foregroundBrush.color()); legendTitleTextAttr.setFontSize(KDChart::Measure(generalFontSize + 4, KDChartEnums::MeasureCalculationModeAbsolute)); legend->setTitleTextAttributes(legendTitleTextAttr); //this sets the line width only for line diagrams setLineWidth(config.chartLineWidth()); //set data value attributes //make sure to show only the required number of fractional digits on the labels of the graph DataValueAttributes dataValueAttr(planeDiagram->dataValueAttributes()); MarkerAttributes markerAttr(dataValueAttr.markerAttributes()); markerAttr.setVisible(true); markerAttr.setMarkerStyle(MarkerAttributes::MarkerCircle); markerAttr.setMarkerSize(QSize(8, 8)); dataValueAttr.setMarkerAttributes(markerAttr); TextAttributes dataValueTextAttr(dataValueAttr.textAttributes()); dataValueTextAttr.setPen(m_foregroundBrush.color()); dataValueAttr.setTextAttributes(dataValueTextAttr); dataValueAttr.setVisible(config.isChartDataLabels()); dataValueAttr.setDecimalDigits(MyMoneyMoney::denomToPrec(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction())); planeDiagram->setDataValueAttributes(dataValueAttr); planeDiagram->setAllowOverlappingDataValueTexts(true); if (qMin(static_cast<uint>(KMyMoneyGlobalSettings::maximumLegendItems()), legend->datasetCount()) < 2) { // the legend is needed only if at least two data sets are rendered removeLegend(); } }
MainWindow::MainWindow( QWidget* parent ) : QWidget( parent ) { setupUi( this ); QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); m_chart = new Chart(); chartLayout->addWidget( m_chart ); #if USE_ROOTINDEX m_model.insertRows( 0,2, QModelIndex() ); m_model.insertColumns( 0,1, QModelIndex() ); QModelIndex idx1 = m_model.index( 0,0,QModelIndex() ); QModelIndex idx2 = m_model.index( 1,0,QModelIndex() ); m_model.setData( idx1, 3.14 ); m_model.setData( idx2, 2*3.14 ); m_model.insertRows( 0,5, idx1 ); m_model.insertColumns( 0,5, idx1 ); for ( int i = 0; i < 5; ++i ) { for ( int j = 0; j < 5; ++j ) { m_model.setData( m_model.index( i,j,idx1), (qreal)i*j ); } } m_model.insertRows( 0,2, idx2 ); m_model.insertColumns( 0,2, idx2 ); for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 2; ++j ) { m_model.setData( m_model.index( i,j,idx2), 10.*(i+1.)/(j+1.) ); } } #else QModelIndex idx1 = QModelIndex(); m_model.insertRows( 0,5, idx1 ); m_model.insertColumns( 0,5, idx1 ); for ( int i = 0; i < 5; ++i ) { for ( int j = 0; j < 5; ++j ) { m_model.setData( m_model.index( i,j,idx1), (qreal)i*j ); } } QModelIndex idx2 = idx1; m_model2.insertRows( 0,2, idx2 ); m_model2.insertColumns( 0,2, idx2 ); for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 2; ++j ) { m_model2.setData( m_model2.index( i,j,idx2), 10.*(i+1.)/(j+1.) ); } } #endif // Set up the diagram m_lines = new LineDiagram(); m_lines->setModel( &m_model ); #if USE_ROOTINDEX m_lines->setRootIndex(idx1); #endif m_bars = new BarDiagram(); #if USE_ROOTINDEX m_bars->setModel( &m_model ); m_bars->setRootIndex(idx2); #else m_bars->setModel( &m_model2 ); #endif plane = new CartesianCoordinatePlane( m_chart ); CartesianAxis *xAxis = new CartesianAxis( m_lines ); CartesianAxis *yAxis = new CartesianAxis ( m_lines ); CartesianAxis *yAxis3 = new CartesianAxis ( m_lines ); xAxis->setPosition ( KChart::CartesianAxis::Bottom ); yAxis->setPosition ( KChart::CartesianAxis::Left ); yAxis3->setPosition ( KChart::CartesianAxis::Left ); CartesianAxis *yAxis2 = new CartesianAxis ( m_bars ); yAxis2->setPosition ( KChart::CartesianAxis::Right ); // explicitly add it to the second diagram, we want to share it m_bars->addAxis( xAxis ); m_chart->coordinatePlane()->replaceDiagram( m_lines ); plane->replaceDiagram( m_bars ); // We want both planes to use the same space. plane->setReferenceCoordinatePlane( m_chart->coordinatePlane() ); m_chart->addCoordinatePlane( plane/*, 1*/); }
void ChartWidget::setModel(ChartModel* model, bool minimalMode) { auto* coordinatePlane = dynamic_cast<CartesianCoordinatePlane*>(m_chart->coordinatePlane()); Q_ASSERT(coordinatePlane); foreach (auto diagram, coordinatePlane->diagrams()) { coordinatePlane->takeDiagram(diagram); delete diagram; } if (minimalMode) { KChart::GridAttributes grid; grid.setSubGridVisible(false); coordinatePlane->setGlobalGridAttributes(grid); } switch (model->type()) { case ChartModel::Consumed: setToolTip(i18n("<qt>Shows the heap memory consumption over time.</qt>")); break; case ChartModel::Allocated: setToolTip(i18n("<qt>Displays total memory allocated over time. " "This value ignores deallocations and just measures heap allocation throughput.</qt>")); break; case ChartModel::Allocations: setToolTip(i18n("<qt>Shows number of memory allocations over time.</qt>")); break; case ChartModel::Temporary: setToolTip(i18n("<qt>Shows number of temporary memory allocations over time. " "A temporary allocation is one that is followed immediately by its " "corresponding deallocation, without other allocations happening in-between.</qt>")); break; } { auto totalPlotter = new Plotter(this); totalPlotter->setAntiAliasing(true); auto totalProxy = new ChartProxy(true, this); totalProxy->setSourceModel(model); totalPlotter->setModel(totalProxy); totalPlotter->setType(Plotter::Stacked); KColorScheme scheme(QPalette::Active, KColorScheme::Window); const QPen foreground(scheme.foreground().color()); auto bottomAxis = new TimeAxis(totalPlotter); auto axisTextAttributes = bottomAxis->textAttributes(); axisTextAttributes.setPen(foreground); bottomAxis->setTextAttributes(axisTextAttributes); auto axisTitleTextAttributes = bottomAxis->titleTextAttributes(); axisTitleTextAttributes.setPen(foreground); auto fontSize = axisTitleTextAttributes.fontSize(); fontSize.setCalculationMode(KChartEnums::MeasureCalculationModeAbsolute); if (minimalMode) { fontSize.setValue(font().pointSizeF() - 2); } else { fontSize.setValue(font().pointSizeF() + 2); } axisTitleTextAttributes.setFontSize(fontSize); bottomAxis->setTitleTextAttributes(axisTitleTextAttributes); bottomAxis->setTitleText(model->headerData(0).toString()); bottomAxis->setPosition(CartesianAxis::Bottom); totalPlotter->addAxis(bottomAxis); CartesianAxis* rightAxis = model->type() == ChartModel::Allocations || model->type() == ChartModel::Temporary ? new CartesianAxis(totalPlotter) : new SizeAxis(totalPlotter); rightAxis->setTextAttributes(axisTextAttributes); rightAxis->setTitleTextAttributes(axisTitleTextAttributes); rightAxis->setTitleText(model->headerData(1).toString()); rightAxis->setPosition(CartesianAxis::Right); totalPlotter->addAxis(rightAxis); coordinatePlane->addDiagram(totalPlotter); } { auto plotter = new Plotter(this); plotter->setAntiAliasing(true); plotter->setType(Plotter::Stacked); auto proxy = new ChartProxy(false, this); proxy->setSourceModel(model); plotter->setModel(proxy); coordinatePlane->addDiagram(plotter); } }
MainWindow::MainWindow( QWidget* parent ) : QWidget( parent ) { setupUi( this ); QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame ); #ifdef USE_FRAME_WIDGET FrameWidget* chartFrameWidget = new FrameWidget(); chartLayout->addWidget( chartFrameWidget ); #endif hSBar->setVisible( false ); vSBar->setVisible( false ); m_model.loadFromCSV( ":/empty" ); // Set up the diagram m_lines = new LineDiagram(); m_lines->setModel( &m_model ); CartesianAxis *xAxis = new CartesianAxis( m_lines ); CartesianAxis *yAxis = new CartesianAxis ( m_lines ); CartesianAxis *axisTop = new CartesianAxis ( m_lines ); CartesianAxis *axisRight = new CartesianAxis ( m_lines ); xAxis->setPosition ( KChart::CartesianAxis::Bottom ); yAxis->setPosition ( KChart::CartesianAxis::Left ); axisTop->setPosition( KChart::CartesianAxis::Top ); axisRight->setPosition( KChart::CartesianAxis::Right ); m_lines->addAxis( xAxis ); m_lines->addAxis( yAxis ); m_lines->addAxis( axisTop ); m_lines->addAxis( axisRight ); m_chart = new Chart(); //m_chart->setGlobalLeading(10,10,10,10); // by default there is no leading #ifdef USE_FRAME_WIDGET chartFrameWidget->setChart( m_chart ); // make sure, we re-draw after changing one of the chart's properties connect( m_chart, SIGNAL( propertiesChanged() ), chartFrameWidget, SLOT( update() ) ) ; #else chartLayout->addWidget( m_chart ); #endif m_chart->coordinatePlane()->replaceDiagram( m_lines ); for ( int iColumn = 0; iColumn<m_lines->model()->columnCount(); ++iColumn ) { QPen pen(m_lines->pen( iColumn )); pen.setWidth(4); m_lines->setPen( iColumn, pen ); } FrameAttributes faChart( m_chart->frameAttributes() ); faChart.setVisible( true ); faChart.setPen( QPen(QColor(0x60,0x60,0xb0), 8) ); m_chart->setFrameAttributes( faChart ); BackgroundAttributes baChart( m_chart->backgroundAttributes() ); baChart.setVisible( true ); baChart.setBrush( QColor(0xd0,0xd0,0xff) ); m_chart->setBackgroundAttributes( baChart ); // Set up the legend m_legend = new Legend( m_lines, m_chart ); m_legend->setPosition( Position::South ); m_legend->setAlignment( Qt::AlignRight ); m_legend->setShowLines( false ); m_legend->setTitleText( tr( "Legend" ) ); m_legend->setOrientation( Qt::Horizontal ); // setting the legend frame and background to the same color: const QColor legendColor(0xff,0xe0,0x80); FrameAttributes faLegend( m_legend->frameAttributes() ); faLegend.setVisible( true ); faLegend.setPen( QPen(legendColor, 1) ); m_legend->setFrameAttributes( faLegend ); BackgroundAttributes baLegend( m_legend->backgroundAttributes() ); baLegend.setVisible( true ); baLegend.setBrush( legendColor ); m_legend->setBackgroundAttributes( baLegend ); m_chart->addLegend( m_legend ); // for illustration we paint the same chart at different sizes: QSize size1 = QSize( 200, 200 ); QSize size2 = QSize( 800, 800 ); m_pix1 = drawIntoPixmap( size1, m_chart ); m_pix2 = drawIntoPixmap( size2, m_chart ); m_pix2 = m_pix2.scaled( size1 ); m_smallChart1 = new QLabel( this ); m_smallChart1->setWindowTitle( "200x200" ); m_smallChart1->setPixmap( m_pix1 ); m_smallChart1->setFixedSize( m_pix1.size() ); m_smallChart1->move( width() - m_pix1.width()*2, height()/2 - m_pix1.height()-5 ); m_smallChart1->show(); m_smallChart2 = new QLabel( this ); m_smallChart2->setWindowTitle( "800x800 scaled down" ); m_smallChart2->setPixmap( m_pix2 ); m_smallChart2->setFixedSize( m_pix2.size() ); m_smallChart2->move( width() - m_pix2.width()*2, height()/2 + 5 ); m_smallChart2->show(); faChart.setPen( QPen(QColor(0xb0,0xb0,0xff), 8) ); m_chart->setFrameAttributes( faChart ); // initialize attributes; this is necessary because we need to enable data value attributes before // any of them (e.g. only markers) can be displayed. but if we enable data value attributs, a default // data value text is included, even if we only wanted to set markers. so we enable DVA and then // individually disable the parts we don't want. on_paintValuesCB_toggled( false ); on_paintMarkersCB_toggled( false ); }