コード例 #1
0
ファイル: chartwidget.cpp プロジェクト: HanumathRao/heaptrack
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);
    }

}
コード例 #2
0
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 );
}
コード例 #3
0
ファイル: kreportchartview.cpp プロジェクト: CGenie/kmymoney
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("&nbsp;", " ");
      }
      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();
  }
}
コード例 #4
0
ファイル: chartwidget.cpp プロジェクト: KDE/heaptrack
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);
    }
}