diff --git a/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.cpp b/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.cpp index 25cc7a28c2..f4c95972e1 100644 --- a/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.cpp +++ b/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.cpp @@ -1,500 +1,523 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // Qmitk #include "ChartExample.h" // Qt #include const std::string ChartExample::VIEW_ID = "org.mitk.views.chartexample"; void ChartExample::SetFocus() { m_Controls.m_buttonCreateChart->setFocus(); } void ChartExample::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); CreateConnectionsForGUIElements(); connect(m_Controls.m_comboBoxChartType, &QComboBox::currentTextChanged, this, &ChartExample::AdaptDataGUI); m_Controls.m_groupBoxErrors->setVisible(false); m_Controls.m_groupBoxXErrors->setVisible(false); m_Controls.m_groupBoxYErrors->setVisible(false); m_Controls.m_lineEditDataXVector->setVisible(false); m_Controls.m_lineEditDataXVector->setText("0;1;2;3;4;5;6;7;8;9"); ResetDataGUI(); m_Controls.m_doubleSpinBox_maxZoomX->setValue(10); m_Controls.m_doubleSpinBox_maxZoomY->setValue(10); FillRandomDataValues(); auto chartStyle = GetColorTheme(); m_Controls.m_Chart->SetTheme(chartStyle); m_Controls.m_lineEditXAxisLabel->setText("xLabel"); m_Controls.m_lineEditYAxisLabel->setText("yLabel"); m_ChartNameToChartType.emplace("bar", QmitkChartWidget::ChartType::bar); m_ChartNameToChartType.emplace("line", QmitkChartWidget::ChartType::line); m_ChartNameToChartType.emplace("spline", QmitkChartWidget::ChartType::spline); m_ChartNameToChartType.emplace("pie", QmitkChartWidget::ChartType::pie); m_ChartNameToChartType.emplace("area", QmitkChartWidget::ChartType::area); m_ChartNameToChartType.emplace("area-spline", QmitkChartWidget::ChartType::area_spline); m_ChartNameToChartType.emplace("scatter", QmitkChartWidget::ChartType::scatter); m_LineNameToLineType.emplace("solid", QmitkChartWidget::LineStyle::solid); m_LineNameToLineType.emplace("dashed", QmitkChartWidget::LineStyle::dashed); m_AxisScaleNameToAxisScaleType.emplace("linear", QmitkChartWidget::AxisScale::linear); m_AxisScaleNameToAxisScaleType.emplace("logarithmic", QmitkChartWidget::AxisScale::log); m_LegendPositionNameToLegendPositionType.emplace("bottom middle", QmitkChartWidget::LegendPosition::bottomMiddle); m_LegendPositionNameToLegendPositionType.emplace("bottom right", QmitkChartWidget::LegendPosition::bottomRight); m_LegendPositionNameToLegendPositionType.emplace("top right", QmitkChartWidget::LegendPosition::topRight); m_LegendPositionNameToLegendPositionType.emplace("top left", QmitkChartWidget::LegendPosition::topLeft); m_LegendPositionNameToLegendPositionType.emplace("middle right", QmitkChartWidget::LegendPosition::middleRight); } void ChartExample::CreateConnectionsForGUIElements() { connect(m_Controls.m_buttonCreateChart, &QPushButton::clicked, this, &ChartExample::CreateChart); connect(m_Controls.m_buttonUpdateChart, &QPushButton::clicked, this, &ChartExample::UpdateChart); connect(m_Controls.m_buttonClearChart, &QPushButton::clicked, this, &ChartExample::ClearChart); connect(m_Controls.m_buttonAddData, &QPushButton::clicked, this, &ChartExample::AddData); connect(m_Controls.m_checkBoxEnableDataX, &QCheckBox::toggled, this, &ChartExample::ShowXData); connect(m_Controls.m_checkBoxEnableErrors, &QCheckBox::toggled, this, &ChartExample::ShowErrorOptions); connect(m_Controls.m_checkBoxEnableXErrors, &QCheckBox::toggled, this, &ChartExample::ShowXErrorOptions); connect(m_Controls.m_checkBoxEnableYErrors, &QCheckBox::toggled, this, &ChartExample::ShowYErrorOptions); connect(m_Controls.m_doubleSpinBox_minZoomX, &QSpinBox::editingFinished, this, &ChartExample::AdaptZoomX); connect(m_Controls.m_doubleSpinBox_maxZoomX, &QSpinBox::editingFinished, this, &ChartExample::AdaptZoomX); connect(m_Controls.m_doubleSpinBox_minZoomY, &QSpinBox::editingFinished, this, &ChartExample::AdaptZoomY); connect(m_Controls.m_doubleSpinBox_maxZoomY, &QSpinBox::editingFinished, this, &ChartExample::AdaptZoomY); connect(m_Controls.m_comboBoxLegendPosition, &QComboBox::currentTextChanged, this, &ChartExample::OnLegendPositionChanged); connect(m_Controls.m_lineEditTitle, &QLineEdit::editingFinished, this, &ChartExample::OnTitleChanged); connect(m_Controls.m_lineEditXAxisLabel, &QLineEdit::editingFinished, this, &ChartExample::OnXAxisLabelChanged); connect(m_Controls.m_lineEditYAxisLabel, &QLineEdit::editingFinished, this, &ChartExample::OnYAxisLabelChanged); connect( m_Controls.m_comboBoxYAxisScale, &QComboBox::currentTextChanged, this, &ChartExample::OnYAxisScaleChanged); connect(m_Controls.m_checkBoxShowLegend, &QCheckBox::stateChanged, this, &ChartExample::OnShowLegendChanged); connect(m_Controls.m_checkBoxStackedData, &QCheckBox::stateChanged, this, &ChartExample::OnStackedDataChanged); connect(m_Controls.m_checkBoxShowDataPoints, &QCheckBox::stateChanged, this, &ChartExample::OnShowDataPointsChanged); connect(m_Controls.m_checkBoxShowSubchart, &QCheckBox::stateChanged, this, &ChartExample::OnShowSubchartChanged); } void ChartExample::CreateChart() { auto dataYAxisScaleType = m_AxisScaleNameToAxisScaleType.at(m_Controls.m_comboBoxYAxisScale->currentText().toStdString()); auto xAxisLabel = m_Controls.m_lineEditXAxisLabel->text().toStdString(); auto yAxisLabel = m_Controls.m_lineEditYAxisLabel->text().toStdString(); auto showLegend = m_Controls.m_checkBoxShowLegend->isChecked(); auto legendPosition = m_LegendPositionNameToLegendPositionType.at(m_Controls.m_comboBoxLegendPosition->currentText().toStdString()); auto showDataPoints = m_Controls.m_checkBoxShowDataPoints->isChecked(); auto stackedData = m_Controls.m_checkBoxStackedData->isChecked(); auto showSubchart = m_Controls.m_checkBoxShowSubchart->isChecked(); auto title = m_Controls.m_lineEditTitle->text().toStdString(); m_Controls.m_Chart->SetTitle(title); m_Controls.m_Chart->SetYAxisScale(dataYAxisScaleType); m_Controls.m_Chart->SetXAxisLabel(xAxisLabel); m_Controls.m_Chart->SetYAxisLabel(yAxisLabel); m_Controls.m_Chart->SetShowLegend(showLegend); m_Controls.m_Chart->SetLegendPosition(legendPosition); m_Controls.m_Chart->SetShowErrorBars(true); m_Controls.m_Chart->SetShowDataPoints(showDataPoints); m_Controls.m_Chart->SetStackedData(stackedData); m_Controls.m_Chart->Show(showSubchart); } +void ChartExample::UpdateData() +{ + if (m_Controls.m_comboBoxExistingData->currentText().isEmpty()) + { + m_Controls.m_labelInfo->setText("Please enter a valid Datalabel"); + m_Controls.m_labelInfo->setStyleSheet("{color: ##ff0000}"); + return; + } + + if (m_Controls.m_lineEditDataLabel->text() != m_Controls.m_comboBoxExistingData->currentText()) + { + return; + } + + auto dataLabel = m_Controls.m_lineEditDataLabel->text().toStdString(); + m_Controls.m_Chart->RemoveData(dataLabel); + + auto it = std::find(labelStorage.begin(), labelStorage.end(), dataLabel); + labelStorage.erase(it); + + auto index = m_Controls.m_comboBoxExistingData->findText(QString::fromStdString(dataLabel)); + m_Controls.m_comboBoxExistingData->removeItem(index); + AddData(); } void ChartExample::ClearChart() { m_Controls.m_Chart->Clear(); m_Controls.m_plainTextEditDataView->clear(); } std::vector ChartExample::ConvertToDoubleVector(const QString &data, QChar delimiter) const { std::vector output; if (data.isEmpty()) { return output; } for (const QString entry : data.split(delimiter)) { output.push_back(entry.toDouble()); } return output; } std::vector ChartExample::ConvertToStringVector(const QString &data, QChar delimiter) const { std::vector output; if (data.isEmpty()) { return output; } for (const QString entry : data.split(delimiter)) { output.push_back(entry.toStdString()); } return output; } void ChartExample::AddData() { QString data = m_Controls.m_lineEditDataYVector->text(); auto dataY = ConvertToDoubleVector(data); auto chartType = m_ChartNameToChartType.at(m_Controls.m_comboBoxChartType->currentText().toStdString()); std::string dataLabel = m_Controls.m_lineEditDataLabel->text().toStdString(); std::string dataColor = m_Controls.m_lineEditColor->text().toStdString(); auto dataLineStyleType = m_LineNameToLineType.at(m_Controls.m_comboBoxLineStyle->currentText().toStdString()); if (m_Controls.m_checkBoxEnableDataX->isChecked()) { QString lineEditDataX = m_Controls.m_lineEditDataXVector->text(); auto dataX = ConvertToDoubleVector(lineEditDataX); if (dataX.size() != dataY.size()) { mitkThrow() << "data x and y size have to be equal"; } auto dataXandY = CreateMap(dataX, dataY); data = QString::fromStdString(ConvertToText(dataXandY)); m_Controls.m_Chart->AddData2D(dataXandY, dataLabel, chartType); } else { m_Controls.m_Chart->AddData1D(dataY, dataLabel, chartType); } if (!dataColor.empty()) { m_Controls.m_Chart->SetColor(dataLabel, dataColor); } if (chartType == QmitkChartWidget::ChartType::pie) { QString pieLabelsData = m_Controls.m_lineEditPieDataLabel->text(); if (!pieLabelsData.isEmpty()) { auto pieLabels = ConvertToStringVector(pieLabelsData); m_Controls.m_Chart->SetPieLabels(pieLabels, dataLabel); } } if (m_Controls.m_checkBoxEnableErrors->isChecked()) { if (m_Controls.m_checkBoxEnableXErrors->isChecked()) { auto errorsPlus = ConvertToDoubleVector(m_Controls.m_lineEditXErrorPlus->text()); auto errorsMinus = ConvertToDoubleVector(m_Controls.m_lineEditXErrorMinus->text()); m_Controls.m_Chart->SetXErrorBars(m_Controls.m_lineEditDataLabel->text().toStdString(), errorsPlus, errorsMinus); } if (m_Controls.m_checkBoxEnableYErrors->isChecked()) { auto errorsPlus = ConvertToDoubleVector(m_Controls.m_lineEditYErrorPlus->text()); auto errorsMinus = ConvertToDoubleVector(m_Controls.m_lineEditYErrorMinus->text()); m_Controls.m_Chart->SetYErrorBars(m_Controls.m_lineEditDataLabel->text().toStdString(), errorsPlus, errorsMinus); } } m_Controls.m_Chart->SetLineStyle(dataLabel, dataLineStyleType); QString dataOverview; dataOverview.append(m_Controls.m_lineEditDataLabel->text()); dataOverview.append("(").append(m_Controls.m_comboBoxChartType->currentText()); if (!dataColor.empty()) { dataOverview.append(", ").append(dataColor.c_str()); } dataOverview.append(", ").append(m_Controls.m_comboBoxLineStyle->currentText()); dataOverview.append(")"); dataOverview.append(":").append(data); m_Controls.m_plainTextEditDataView->appendPlainText(dataOverview); FillRandomDataValues(); } void ChartExample::ShowXData(bool show) { m_Controls.m_lineEditDataXVector->setVisible(show); } void ChartExample::ShowErrorOptions(bool show) { m_Controls.m_groupBoxErrors->setVisible(show); } void ChartExample::ShowXErrorOptions(bool show) { m_Controls.m_groupBoxXErrors->setVisible(show); } void ChartExample::ShowYErrorOptions(bool show) { m_Controls.m_groupBoxYErrors->setVisible(show); } void ChartExample::AdaptZoomX() { m_Controls.m_Chart->SetMinMaxValueXView(m_Controls.m_doubleSpinBox_minZoomX->value(), m_Controls.m_doubleSpinBox_maxZoomX->value()); m_Controls.m_Chart->Show(); } void ChartExample::AdaptZoomY() { m_Controls.m_Chart->SetMinMaxValueYView(m_Controls.m_doubleSpinBox_minZoomY->value(), m_Controls.m_doubleSpinBox_maxZoomY->value()); m_Controls.m_Chart->Show(); } void ChartExample::AdaptDataGUI(const QString &chartType) { auto chartTypeEnum = m_ChartNameToChartType.at(chartType.toLower().toStdString()); if (chartTypeEnum == QmitkChartWidget::ChartType::pie) { m_Controls.m_labelPieData->setVisible(true); m_Controls.m_lineEditPieDataLabel->setVisible(true); m_Controls.m_labelLineStyle->setVisible(false); m_Controls.m_comboBoxLineStyle->setVisible(false); } else if (chartTypeEnum != QmitkChartWidget::ChartType::pie) { m_Controls.m_labelLineStyle->setVisible(true); m_Controls.m_comboBoxLineStyle->setVisible(true); m_Controls.m_labelPieData->setVisible(false); m_Controls.m_lineEditPieDataLabel->setVisible(false); } } std::vector ChartExample::GenerateRandomNumbers(unsigned int amount, double max) const { QRandomGenerator gen; gen.seed(time(nullptr)); std::vector data; for (unsigned int i = 0; i < amount; i++) { data.push_back(gen.bounded(max)); } return data; } std::map ChartExample::CreateMap(std::vector keys, std::vector values) const { std::map aMap; std::transform(keys.begin(), keys.end(), values.begin(), std::inserter(aMap, aMap.end()), [](double a, double b) { return std::make_pair(a, b); }); return aMap; } std::string ChartExample::ConvertToText(std::vector numbers, std::string delimiter) const { std::ostringstream oss; oss.precision(3); if (!numbers.empty()) { for (auto number : numbers) { oss << number << delimiter; } } auto aString = oss.str(); aString.pop_back(); return aString; } std::string ChartExample::ConvertToText(std::map numbers, std::string delimiter) const { std::ostringstream oss; oss.precision(3); if (!numbers.empty()) { for (const auto keyValue : numbers) { oss << keyValue.first << ":" << keyValue.second << delimiter; } } auto aString = oss.str(); aString.pop_back(); return aString; } QmitkChartWidget::ColorTheme ChartExample::GetColorTheme() const { ctkPluginContext *context = berry::WorkbenchPlugin::GetDefault()->GetPluginContext(); ctkServiceReference styleManagerRef = context->getServiceReference(); if (styleManagerRef) { auto styleManager = context->getService(styleManagerRef); if (styleManager->GetStyle().name == "Dark") { return QmitkChartWidget::ColorTheme::darkstyle; } else { return QmitkChartWidget::ColorTheme::lightstyle; } } return QmitkChartWidget::ColorTheme::darkstyle; } void ChartExample::OnLegendPositionChanged(const QString &newText) { auto legendPosition = m_LegendPositionNameToLegendPositionType.at(newText.toStdString()); m_Controls.m_Chart->SetLegendPosition(legendPosition); } void ChartExample::OnTitleChanged() { auto newTitle = m_Controls.m_lineEditTitle->text(); m_Controls.m_Chart->SetTitle(newTitle.toStdString()); } void ChartExample::OnXAxisLabelChanged() { auto newXAxisLabel = m_Controls.m_lineEditXAxisLabel->text(); m_Controls.m_Chart->SetXAxisLabel(newXAxisLabel.toStdString()); } void ChartExample::OnYAxisLabelChanged() { auto newYAxisLabel = m_Controls.m_lineEditYAxisLabel->text(); m_Controls.m_Chart->SetYAxisLabel(newYAxisLabel.toStdString()); } void ChartExample::OnYAxisScaleChanged(const QString &newYAxisScale) { auto yAxisScale = m_AxisScaleNameToAxisScaleType.at(newYAxisScale.toStdString()); m_Controls.m_Chart->SetYAxisScale(yAxisScale); } void ChartExample::OnShowLegendChanged(int newState) { m_Controls.m_Chart->SetShowLegend(newState == Qt::Checked); } void ChartExample::OnStackedDataChanged(int newState) { m_Controls.m_Chart->SetStackedData(newState == Qt::Checked); } void ChartExample::OnShowDataPointsChanged(int newState) { m_Controls.m_Chart->SetShowDataPoints(newState == Qt::Checked); } void ChartExample::OnShowSubchartChanged(int newState) { m_Controls.m_Chart->SetShowSubchart(newState == Qt::Checked); } void ChartExample::UpdateSelectedData() { std::string label = m_Controls.m_comboBoxExistingData->currentText().toStdString(); auto data = m_Controls.m_Chart->GetDataElementByLabel(label); if (data == nullptr) { return; } auto x = data->GetXData(); auto y = data->GetYData(); auto xVector = x.toVector().toStdVector(); auto yVector = y.toVector().toStdVector(); std::string xString; std::string yString; for (int i = 0; i < xVector.size(); i++) { xString.append(xVector[i].toString().toStdString()); if (i != xVector.size() - 1) { xString.append(";"); } } for (int i = 0; i < yVector.size(); i++) { yString.append(yVector[i].toString().toStdString()); if (i != yVector.size() - 1) { yString.append(";"); } } auto color = data->GetColor(); auto type = data->GetChartType(); auto style = data->GetLineStyle(); int colorIndex = m_Controls.m_Chart->GetIndexByString(color.toString().toStdString()); int typeIndex = m_Controls.m_Chart->GetIndexByString(type.toString().toStdString()); int styleIndex = m_Controls.m_Chart->GetIndexByString(style.toString().toStdString()); if (type.toString() == "pie") { m_Controls.m_comboBoxLineStyle->setVisible(false); m_Controls.m_labelLineStyle->setVisible(false); m_Controls.m_lineEditPieDataLabel->setVisible(true); m_Controls.m_labelPieData->setVisible(true); auto pieLabels = data->GetPieLabels(); auto pieLabelsVector = pieLabels.toVector().toStdVector(); std::string pieLabelsString; for (int i = 0; i < pieLabelsVector.size(); i++) { pieLabelsString.append(pieLabelsVector[i].toString().toStdString()); if (i != pieLabelsVector.size() - 1) { pieLabelsString.append(";"); } } m_Controls.m_lineEditPieDataLabel->setText(QString::fromStdString(pieLabelsString)); } else { m_Controls.m_lineEditPieDataLabel->setVisible(false); m_Controls.m_labelPieData->setVisible(false); m_Controls.m_comboBoxLineStyle->setVisible(true); m_Controls.m_labelLineStyle->setVisible(true); m_Controls.m_comboBoxLineStyle->setCurrentIndex(styleIndex); } m_Controls.m_lineEditDataXVector->setText(QString::fromStdString(xString)); m_Controls.m_lineEditDataYVector->setText(QString::fromStdString(yString)); m_Controls.m_lineEditDataLabel->setText(QString::fromStdString(label)); m_Controls.m_comboBoxColor->setCurrentIndex(colorIndex); m_Controls.m_comboBoxChartType->setCurrentIndex(typeIndex); }