diff --git a/Modules/Chart/include/QmitkChartxyData.h b/Modules/Chart/include/QmitkChartxyData.h index cbf11625af..ee19a2810b 100644 --- a/Modules/Chart/include/QmitkChartxyData.h +++ b/Modules/Chart/include/QmitkChartxyData.h @@ -1,163 +1,165 @@ /*=================================================================== 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. ===================================================================*/ #ifndef QmitkC3xyData_h #define QmitkC3xyData_h #include /** /brief This class holds the actual data for the chart generation with C3. * data can be loaded in constructor directly or with SetData * It is derived from QObject, because we need Q_PROPERTIES to send Data via QWebChannel to JavaScript. */ class QmitkChartxyData : public QObject { Q_OBJECT Q_PROPERTY(QVariant m_LabelCount READ GetLabelCount CONSTANT); Q_PROPERTY(QList m_YData READ GetYData WRITE SetYData NOTIFY SignalDataChanged); Q_PROPERTY(QList m_XData READ GetXData WRITE SetXData NOTIFY SignalDataChanged); Q_PROPERTY( QList m_XErrorDataPlus READ GetXErrorDataPlus WRITE SetXErrorDataPlus NOTIFY SignalErrorDataChanged); Q_PROPERTY( QList m_XErrorDataMinus READ GetXErrorDataMinus WRITE SetXErrorDataMinus NOTIFY SignalErrorDataChanged); Q_PROPERTY( QList m_YErrorDataPlus READ GetYErrorDataPlus WRITE SetYErrorDataPlus NOTIFY SignalErrorDataChanged); Q_PROPERTY( QList m_YErrorDataMinus READ GetYErrorDataMinus WRITE SetYErrorDataMinus NOTIFY SignalErrorDataChanged); Q_PROPERTY( QList m_PieLabels READ GetPieLabels WRITE SetPieLabels NOTIFY SignalPieLabelsChanged); Q_PROPERTY(QVariant m_ChartType READ GetChartType WRITE SetChartType NOTIFY SignalDiagramTypeChanged); Q_PROPERTY(QVariant m_Color READ GetColor WRITE SetColor NOTIFY SignalColorChanged); Q_PROPERTY(QVariant m_Label READ GetLabel WRITE SetLabel NOTIFY SignalLabelChanged); Q_PROPERTY(QVariant m_LineStyleName READ GetLineStyle WRITE SetLineStyle NOTIFY SignalLineStyleChanged); public: explicit QmitkChartxyData(const QMap &data, const QVariant &label, const QVariant &diagramType, const QVariant &position); // Constructor for Data2D (x:y=1:2, 2:6, 3:7) void SetData(const QMap &data); Q_INVOKABLE QVariant GetLabelCount() const { return m_LabelCount; } Q_INVOKABLE QList GetYData() const { return m_YData; }; Q_INVOKABLE void SetYData(const QList &yData) { m_YData = yData; emit SignalDataChanged(yData); }; Q_INVOKABLE QList GetXData() const { return m_XData; }; Q_INVOKABLE void SetXData(const QList &xData) { m_XData = xData; emit SignalDataChanged(xData); }; Q_INVOKABLE QList GetXErrorDataPlus() const { return m_XErrorDataPlus; }; Q_INVOKABLE void SetXErrorDataPlus(const QList &errorData) { m_XErrorDataPlus = errorData; emit SignalErrorDataChanged(errorData); }; Q_INVOKABLE QList GetXErrorDataMinus() const { return m_XErrorDataMinus; }; Q_INVOKABLE void SetXErrorDataMinus(const QList &errorData) { m_XErrorDataMinus = errorData; emit SignalErrorDataChanged(errorData); }; Q_INVOKABLE QList GetYErrorDataPlus() const { return m_YErrorDataPlus; }; Q_INVOKABLE void SetYErrorDataPlus(const QList &errorData) { m_YErrorDataPlus = errorData; emit SignalErrorDataChanged(errorData); }; Q_INVOKABLE QList GetYErrorDataMinus() const { return m_YErrorDataMinus; }; Q_INVOKABLE void SetYErrorDataMinus(const QList &errorData) { m_YErrorDataMinus = errorData; emit SignalErrorDataChanged(errorData); }; Q_INVOKABLE QVariant GetChartType() const { return m_ChartType; }; Q_INVOKABLE void SetChartType(const QVariant &chartType) { m_ChartType = chartType; emit SignalDiagramTypeChanged(chartType); }; Q_INVOKABLE QVariant GetLabel() const { return m_Label; }; Q_INVOKABLE void SetLabel(const QVariant &label) { m_Label = label; emit SignalLabelChanged(label); }; Q_INVOKABLE QList GetPieLabels() const { return m_PieLabels; }; Q_INVOKABLE void SetPieLabels(const QList &pieLabels) { m_PieLabels = pieLabels; }; Q_INVOKABLE QVariant GetColor() const { return m_Color; }; Q_INVOKABLE void SetColor(const QVariant &color) { m_Color = color; emit SignalColorChanged(color); }; Q_INVOKABLE QVariant GetLineStyle() const { return m_LineStyleName; }; Q_INVOKABLE void SetLineStyle(const QVariant &lineStyle) { m_LineStyleName = lineStyle; emit SignalLineStyleChanged(lineStyle); }; /** * \brief Clears the Data. * * This function clears the data (including error data). */ void ClearData(); + QmitkChartxyData() {} + signals: void SignalDataChanged(const QList data); void SignalErrorDataChanged(const QList errorData); void SignalDiagramTypeChanged(const QVariant diagramType); void SignalColorChanged(const QVariant color); void SignalLabelChanged(const QVariant label); void SignalPieLabelsChanged(const QList pieLabels); void SignalLineStyleChanged(const QVariant lineStyle); private: /** js needs to know which label position in the list QmitkChartWidget::Impl::m_C3xyData it has for updating the values*/ const QVariant m_LabelCount; QList m_YData; QList m_XData; QList m_XErrorDataPlus; QList m_XErrorDataMinus; QList m_YErrorDataPlus; QList m_YErrorDataMinus; QVariant m_Label; QList m_PieLabels; QVariant m_ChartType; QVariant m_Color; QVariant m_LineStyleName; }; #endif // QmitkC3xyData_h 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 3856539955..497db0bf57 100644 --- a/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.cpp +++ b/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.cpp @@ -1,551 +1,448 @@ /*=================================================================== 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" #include -// Qt -#include - const std::string ChartExample::VIEW_ID = "org.mitk.views.chartexample"; -static std::vector labelStorage; - 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_lineEditDataXVector->setText("0;1;2;3;4;5;6;7;8;9"); m_Controls.m_lineEditDataYVector->setText("0;1;2;3;4;5;6;7;8;9"); m_Controls.m_lineEditDataLabel->setText("Test"); m_Controls.m_lineEditXAxisLabel->setText("X-Axis"); m_Controls.m_lineEditYAxisLabel->setText("Y-Axis"); m_Controls.m_lineEditTitle->setText("Title"); m_Controls.m_labelPieData->setVisible(false); m_Controls.m_lineEditPieDataLabel->setVisible(false); m_Controls.m_groupBoxErrors->setVisible(false); m_Controls.m_groupBoxXErrors->setVisible(false); m_Controls.m_groupBoxYErrors->setVisible(false); m_Controls.m_doubleSpinBox_maxZoomX->setValue(10); m_Controls.m_doubleSpinBox_maxZoomY->setValue(10); - - 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_ChartNameToChartColor.emplace("red", QmitkChartWidget::ChartColor::red); - m_ChartNameToChartColor.emplace("orange", QmitkChartWidget::ChartColor::orange); - m_ChartNameToChartColor.emplace("yellow", QmitkChartWidget::ChartColor::yellow); - m_ChartNameToChartColor.emplace("green", QmitkChartWidget::ChartColor::green); - m_ChartNameToChartColor.emplace("blue", QmitkChartWidget::ChartColor::blue); - m_ChartNameToChartColor.emplace("purple", QmitkChartWidget::ChartColor::purple); - m_ChartNameToChartColor.emplace("brown", QmitkChartWidget::ChartColor::brown); - m_ChartNameToChartColor.emplace("magenta", QmitkChartWidget::ChartColor::magenta); - m_ChartNameToChartColor.emplace("tan", QmitkChartWidget::ChartColor::tan); - m_ChartNameToChartColor.emplace("cyan", QmitkChartWidget::ChartColor::cyan); - m_ChartNameToChartColor.emplace("olive", QmitkChartWidget::ChartColor::olive); - m_ChartNameToChartColor.emplace("maroon", QmitkChartWidget::ChartColor::maroon); - m_ChartNameToChartColor.emplace("navy", QmitkChartWidget::ChartColor::navy); - m_ChartNameToChartColor.emplace("aquamarine", QmitkChartWidget::ChartColor::aquamarine); - m_ChartNameToChartColor.emplace("turquoise", QmitkChartWidget::ChartColor::turqouise); - m_ChartNameToChartColor.emplace("silver", QmitkChartWidget::ChartColor::silver); - m_ChartNameToChartColor.emplace("lime", QmitkChartWidget::ChartColor::lime); - m_ChartNameToChartColor.emplace("teal", QmitkChartWidget::ChartColor::teal); - m_ChartNameToChartColor.emplace("indigo", QmitkChartWidget::ChartColor::indigo); - m_ChartNameToChartColor.emplace("violet", QmitkChartWidget::ChartColor::violet); - m_ChartNameToChartColor.emplace("pink", QmitkChartWidget::ChartColor::pink); - m_ChartNameToChartColor.emplace("black", QmitkChartWidget::ChartColor::black); - m_ChartNameToChartColor.emplace("white", QmitkChartWidget::ChartColor::white); - m_ChartNameToChartColor.emplace("grey", QmitkChartWidget::ChartColor::grey); - - 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_buttonUpdateData, &QPushButton::clicked, this, &ChartExample::UpdateData); connect(m_Controls.m_buttonClearChart, &QPushButton::clicked, this, &ChartExample::ClearChart); connect(m_Controls.m_buttonAddData, &QPushButton::clicked, this, &ChartExample::AddData); connect(m_Controls.m_comboBoxExistingData, &QComboBox::currentTextChanged, this, &ChartExample::UpdateSelectedData); 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::AddData() +{ + QString lineEditDataX = m_Controls.m_lineEditDataXVector->text(); + QString lineEditDataY = m_Controls.m_lineEditDataYVector->text(); + auto dataX = ConvertToDoubleVector(lineEditDataX); + auto dataY = ConvertToDoubleVector(lineEditDataY); + auto dataXandY = CreateMap(dataX, dataY); + QString data = QString::fromStdString(ConvertToText(dataXandY)); + + QString dataLabel = m_Controls.m_lineEditDataLabel->text(); + QString chartColor = m_Controls.m_comboBoxColor->currentText(); + QString chartType = m_Controls.m_comboBoxChartType->currentText(); + QString chartStyle = m_Controls.m_comboBoxLineStyle->currentText(); + + if (std::find(labelStorage.begin(), labelStorage.end(), dataLabel) != labelStorage.end()) + { + m_Controls.m_labelInfo->setText("This data already exists"); + m_Controls.m_labelInfo->setStyleSheet("color: red;"); + return; + } + + if (dataX.size() != dataY.size()) + { + m_Controls.m_labelInfo->setText("Data x and y size have to be equal"); + m_Controls.m_labelInfo->setStyleSheet("color: red;"); + return; + } + + QString pieLabelsData = m_Controls.m_lineEditPieDataLabel->text(); + + std::string chartTypeAsString = chartType.toStdString(); + std::string pieAsString = "Pie"; + if (chartTypeAsString == pieAsString) + { + if (!pieLabelsData.isEmpty()) + { + auto pieLabels = ConvertToStringVector(pieLabelsData); + m_Controls.m_Chart->SetPieLabels(pieLabels, dataLabel.toStdString()); + } + } + + labelStorage.push_back(dataLabel); + m_Controls.m_Chart->AddChartExampleData(dataXandY, dataLabel, chartType, chartColor, chartStyle, pieLabelsData); + m_Controls.m_comboBoxExistingData->addItem(m_Controls.m_lineEditDataLabel->text()); + + 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.toStdString(), chartStyle); + + QString dataOverview; + dataOverview.append(m_Controls.m_lineEditDataLabel->text()); + dataOverview.append("(").append(m_Controls.m_comboBoxChartType->currentText()); + + dataOverview.append(", ").append(m_Controls.m_comboBoxLineStyle->currentText()); + dataOverview.append(")"); + dataOverview.append(":").append(data); + + m_Controls.m_plainTextEditDataView->appendPlainText(dataOverview); +} + 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); + + m_Controls.m_Chart->chartExistence = true; } 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: red;"); 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() +void ChartExample::UpdateSelectedData() { - m_Controls.m_Chart->Clear(); + std::string label = m_Controls.m_comboBoxExistingData->currentText().toStdString(); + auto data = m_Controls.m_Chart->GetDataElementByLabel(label); - m_Controls.m_plainTextEditDataView->clear(); - - m_Controls.m_comboBoxExistingData->clear(); - - labelStorage.clear(); -} - -std::vector ChartExample::ConvertToDoubleVector(const QString &data, QChar delimiter) const -{ - std::vector output; - if (data.isEmpty()) - { - return output; - } + if (data == nullptr) + { + return; + } - for (const QString entry : data.split(delimiter)) - { - output.push_back(entry.toDouble()); - } - return output; -} + auto x = data->GetXData(); + auto y = data->GetYData(); -std::vector ChartExample::ConvertToStringVector(const QString &data, QChar delimiter) const -{ - std::vector output; - if (data.isEmpty()) - { - return output; - } + auto xVector = x.toVector().toStdVector(); + auto yVector = y.toVector().toStdVector(); - for (const QString entry : data.split(delimiter)) - { - output.push_back(entry.toStdString()); - } - return output; -} + QString xString = QString::fromStdString(ConvertToText(xVector)); + QString yString = QString::fromStdString(ConvertToText(yVector)); -void ChartExample::AddData() -{ - QString lineEditDataX = m_Controls.m_lineEditDataXVector->text(); - auto dataX = ConvertToDoubleVector(lineEditDataX); + auto color = data->GetColor(); + auto type = data->GetChartType(); + auto style = data->GetLineStyle(); - QString lineEditDataY = m_Controls.m_lineEditDataYVector->text(); - auto dataY = ConvertToDoubleVector(lineEditDataY); + 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()); - std::string dataLabel = m_Controls.m_lineEditDataLabel->text().toStdString(); - auto chartColor = m_ChartNameToChartColor.at(m_Controls.m_comboBoxColor->currentText().toLower().toStdString()); - auto chartType = m_ChartNameToChartType.at(m_Controls.m_comboBoxChartType->currentText().toLower().toStdString()); - auto chartStyle = m_LineNameToLineType.at(m_Controls.m_comboBoxLineStyle->currentText().toLower().toStdString()); + std::string chartTypeAsString = type.toString().toStdString(); + std::string pieAsString = "Pie"; + if (chartTypeAsString == pieAsString) + { + m_Controls.m_comboBoxLineStyle->setVisible(false); + m_Controls.m_labelLineStyle->setVisible(false); + m_Controls.m_lineEditPieDataLabel->setVisible(true); + m_Controls.m_labelPieData->setVisible(true); - if (std::find(labelStorage.begin(), labelStorage.end(), dataLabel) != labelStorage.end()) - { - m_Controls.m_labelInfo->setText("This data already exists"); - m_Controls.m_labelInfo->setStyleSheet("color: red;"); - return; - } + auto pieLabels = data->GetPieLabels(); - if (dataX.size() != dataY.size()) - { - m_Controls.m_labelInfo->setText("Data x and y size have to be equal"); - m_Controls.m_labelInfo->setStyleSheet("color: red;"); - return; - } - auto dataXandY = CreateMap(dataX, dataY); - QString data = QString::fromStdString(ConvertToText(dataXandY)); + auto pieLabelsVector = pieLabels.toVector().toStdVector(); - QString pieLabelsData = m_Controls.m_lineEditPieDataLabel->text(); + QString pieLabelsString = QString::fromStdString(ConvertToText(pieLabelsVector)); - if (chartType == QmitkChartWidget::ChartType::pie) - { - if (!pieLabelsData.isEmpty()) - { - auto pieLabels = ConvertToStringVector(pieLabelsData); - m_Controls.m_Chart->SetPieLabels(pieLabels, dataLabel); - } - } - labelStorage.push_back(dataLabel); - m_Controls.m_Chart->AddChartExampleData(dataXandY, dataLabel, chartType, chartColor, chartStyle, pieLabelsData); - m_Controls.m_comboBoxExistingData->addItem(m_Controls.m_lineEditDataLabel->text()); - - 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); + m_Controls.m_lineEditPieDataLabel->setText(pieLabelsString); } - if (m_Controls.m_checkBoxEnableYErrors->isChecked()) + + else { - 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_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_Chart->SetLineStyle(dataLabel, chartStyle); - - QString dataOverview; - dataOverview.append(m_Controls.m_lineEditDataLabel->text()); - dataOverview.append("(").append(m_Controls.m_comboBoxChartType->currentText()); - dataOverview.append(", ").append(m_Controls.m_comboBoxLineStyle->currentText()); - dataOverview.append(")"); - dataOverview.append(":").append(data); + m_Controls.m_lineEditDataXVector->setText(xString); + m_Controls.m_lineEditDataYVector->setText(yString); + m_Controls.m_lineEditDataLabel->setText(QString::fromStdString(label)); + m_Controls.m_comboBoxColor->setCurrentIndex(colorIndex); + m_Controls.m_comboBoxChartType->setCurrentIndex(typeIndex); - m_Controls.m_plainTextEditDataView->appendPlainText(dataOverview); } -void ChartExample::ShowXData(bool show) +void ChartExample::ClearChart() { - m_Controls.m_lineEditDataXVector->setVisible(show); + m_Controls.m_Chart->Clear(m_Controls.m_Chart->chartExistence); + + m_Controls.m_plainTextEditDataView->clear(); + + m_Controls.m_comboBoxExistingData->clear(); + + labelStorage.clear(); + + m_Controls.m_Chart->chartExistence = false; } 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) +void ChartExample::AdaptDataGUI(QString chartType) { - auto chartTypeEnum = m_ChartNameToChartType.at(chartType.toLower().toStdString()); - if (chartTypeEnum == QmitkChartWidget::ChartType::pie) + std::string chartTypeAsString = chartType.toStdString(); + std::string PieAsString = "Pie"; + if (chartTypeAsString == PieAsString) { 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) + + else { 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::map ChartExample::CreateMap(std::vector keys, std::vector values) const { - 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()); + 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; +} - 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); +std::string ChartExample::ConvertToText(std::map numbers, std::string delimiter) const +{ + std::ostringstream oss; + oss.precision(3); - auto pieLabels = data->GetPieLabels(); + if (!numbers.empty()) + { + for (const auto keyValue : numbers) + { + oss << keyValue.first << ":" << keyValue.second << delimiter; + } + } + auto aString = oss.str(); + aString.pop_back(); + return aString; +} - auto pieLabelsVector = pieLabels.toVector().toStdVector(); +std::string ChartExample::ConvertToText(std::vector numbers, std::string delimiter) const +{ + std::ostringstream oss; + oss.precision(3); - std::string pieLabelsString; + if (!numbers.empty()) + { + for (auto number : numbers) + { + oss << number.toDouble() << delimiter; + } + } + auto aString = oss.str(); + aString.pop_back(); + return aString; +} - for (int i = 0; i < pieLabelsVector.size(); i++) - { - pieLabelsString.append(pieLabelsVector[i].toString().toStdString()); - if (i != pieLabelsVector.size() - 1) - { - pieLabelsString.append(";"); - } - } +std::vector ChartExample::ConvertToDoubleVector(const QString& data, QChar delimiter) const +{ + std::vector output; + if (data.isEmpty()) + { + return output; + } - m_Controls.m_lineEditPieDataLabel->setText(QString::fromStdString(pieLabelsString)); - } + for (const QString entry : data.split(delimiter)) + { + output.push_back(entry.toDouble()); + } + return output; +} - 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); +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; +} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.h b/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.h index 84ead87aee..530418df05 100644 --- a/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.h +++ b/Plugins/org.mitk.gui.qt.chartExample/src/internal/ChartExample.h @@ -1,92 +1,87 @@ /*=================================================================== 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. ===================================================================*/ #ifndef ChartExample_h #define ChartExample_h #include #include "ui_ChartExampleControls.h" /** \brief Basic example for use of module mitkChart \sa QmitkAbstractView \ingroup ${plugin_target}_internal */ class ChartExample : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; protected: virtual void CreateQtPartControl(QWidget *parent) override; void CreateConnectionsForGUIElements(); virtual void SetFocus() override; + void AddData(); void CreateChart(); void UpdateData(); + void UpdateSelectedData(); void ClearChart(); - void AddData(); - - void ShowXData(bool show); void ShowErrorOptions(bool show); void ShowXErrorOptions(bool show); void ShowYErrorOptions(bool show); void AdaptZoomX(); void AdaptZoomY(); - void AdaptDataGUI(const QString &chartType); - - void UpdateSelectedData(); + void AdaptDataGUI(QString chartType); private: - std::vector GenerateRandomNumbers(unsigned int amount, double max) const; - std::vector ConvertToDoubleVector(const QString &data, QChar delimiter = ';') const; - std::vector ConvertToStringVector(const QString &data, QChar delimiter = ';') const; - std::map CreateMap(std::vector keys, std::vector values) const; - std::string ConvertToText(std::vector numbers, std::string delimiter = ";") const; - std::string ConvertToText(std::map numbers, std::string delimiter = ";") const; - QmitkChartWidget::ColorTheme GetColorTheme() const; + std::map m_AxisScaleNameToAxisScaleType; + std::map m_LegendPositionNameToLegendPositionType; + + std::vector labelStorage; + void OnLegendPositionChanged(const QString &newPosition); void OnTitleChanged(); void OnXAxisLabelChanged(); void OnYAxisLabelChanged(); void OnYAxisScaleChanged(const QString &newYAxisScale); void OnShowLegendChanged(int newState); void OnStackedDataChanged(int newState); void OnShowDataPointsChanged(int newState); void OnShowSubchartChanged(int newState); - std::map m_ChartNameToChartType; - std::map m_ChartNameToChartColor; - std::map m_LineNameToLineType; - std::map m_AxisScaleNameToAxisScaleType; - std::map m_LegendPositionNameToLegendPositionType; + std::map CreateMap(std::vector keys, std::vector values) const; + std::string ConvertToText(std::vector numbers, std::string delimiter = ";") const; + std::string ConvertToText(std::map numbers, std::string delimiter = ";") const; + std::vector ConvertToDoubleVector(const QString& data, QChar delimiter = ';') const; + std::vector ConvertToStringVector(const QString& data, QChar delimiter = ';') const; unsigned int countForUID = 0; Ui::ChartExampleControls m_Controls; }; #endif // ChartExample_h