diff --git a/Modules/Chart/include/QmitkChartWidget.h b/Modules/Chart/include/QmitkChartWidget.h index b9a18b2ed4..c3471ef820 100644 --- a/Modules/Chart/include/QmitkChartWidget.h +++ b/Modules/Chart/include/QmitkChartWidget.h @@ -1,357 +1,356 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkC3jsWidget_h #define QmitkC3jsWidget_h #include #include #include #include class QmitkChartxyData; /*! \brief QmitkChartWidget is a widget to display various charts based on the javascript chart library plotly. * \details Data is added via AddData1D() or AddData2D().\n * There can be multiple charts (of different types with different properties) created by calling AddData1D or AddData2D multiple times.\n\n * The following chart types are supported: * * line chart * * bar chart * * spline chart * * pie chart * * scatter chart * * area chart * * area spline chart. * * Technical details: The javascript code is embedded in a QWebEngineView. The actual js code is implemented in resource\Chart.js. * \sa https://plot.ly/javascript/ for further information about the used javaScript library. * \ingroup Modules/Chart */ class MITKCHART_EXPORT QmitkChartWidget : public QWidget { Q_OBJECT public: /*! * \brief enum of diagram types. */ enum class ChartType { bar, /*!< bar chart, see https://plot.ly/javascript/bar-charts/ */ line, /*!< line chart, see https://plot.ly/javascript/line-charts/ */ spline, /*!< spline chart (smoothed line chart), see https://plot.ly/~jduelfer/23/spline/#/ */ pie, /*!< pie chart, see https://plot.ly/javascript/pie-charts/ */ area, /*!< area chart, see https://plot.ly/javascript/filled-area-plots/ */ area_spline, /*!< area-spline chart, similar to https://plot.ly/~jduelfer/23/spline/#/ */ scatter /*!< scatter chart, see https://plot.ly/javascript/line-and-scatter/ */ }; /*! * \brief enum of chart style (modifies background and line color). */ enum class ColorTheme { darkstyle, /*!< background color: dark gray, foreground color: white*/ lightstyle /*!< background color: white, foreground color: black */ }; enum class LineStyle { solid, dashed }; enum class MarkerSymbol { circle, diamond, cross, square, pentagon, star, x, diamond_tall, star_diamond, star_triangle_up, star_triangle_down, asterisk, cross_thin, x_thin }; enum class ChartColor { red, orange, yellow, green, blue, purple, brown, magenta, tan, cyan, olive, maroon, navy, aquamarine, turqouise, silver, lime, teal, indigo, violet, pink, black, white, grey }; enum class AxisScale { linear, log }; /*! * \brief enum of legend position. * See https://plot.ly/javascript/legend/ */ enum class LegendPosition { bottomMiddle, bottomRight, topRight, topLeft, middleRight }; explicit QmitkChartWidget(QWidget* parent = nullptr); //for UnitTests explicit QmitkChartWidget(QWidget *parent, bool unitTest); ~QmitkChartWidget() override; /*! * \brief Adds 1D data to the widget * \details internally, the list is converted to a map with increasing integers keys starting at 0. * \param label the name of the data that is also used as identifier. * \param chartType the chart type that should be used for this data entry * \note the data can be cleared with ClearDiagram() * \note If the label name already exists, the name is replaced with a unique one by concatenating numbers to it. * \warning Pie chart is significantly different than the other chart types. Here, the data given by AddData1D is summed. Each entry represents a different category. */ void AddData1D(const std::vector& data1D, const std::string& label, ChartType chartType = ChartType::bar); /*! * \brief Updates data of an existing label * \param data1D the 1D data , \sa AddData1D * \param label the (existing) label * \note if the label does not exist, nothing happens */ void UpdateData1D(const std::vector &data1D, const std::string &label); /*! * \sa UpdateData1D * \sa AddData2D */ void UpdateData2D(const std::vector< std::pair > &data2D, const std::string &label); + void UpdateChartExampleData(const std::vector< std::pair >& data2D, + const std::string& label, + const std::string& type, + const std::string& color, + const std::string& lineStyle, + const std::string& pieLabelsData = 0); + /*! * \brief Adds 2D data to the widget. Call repeatedly for displaying multiple charts. * \details each entry represents a data point: key: value --> x-value: y-value. * \param label the name of the data that is also used as identifier. * \param chartType the chart type that should be used for this data entry * \note the data can be cleared with ClearDiagram() * \note If the label name already exists, the name is replaced with a unique one by concatenating numbers to it. * \warning Pie chart is significantly different than the other chart types. Here, the data given by AddData1D is summed. Each entry represents a different category. */ - - void UpdateChartExampleData(const std::vector< std::pair >& data2D, - const std::string& label, - const std::string& type, - const std::string& color, - const std::string& lineStyle, - const std::string& pieLabelsData = 0); - void AddData2D(const std::vector< std::pair > &data2D, const std::string &label, ChartType chartType = ChartType::bar); //Add Function for the ChartExample void AddChartExampleData(const std::vector< std::pair >& data2D, const std::string& label, const std::string& type, const std::string& color, const std::string& style, const std::string& pieLabelsData = 0); /*! * \brief Removes data from the widget, works for 1D and 2D Data * \param label the name of the data that is also used as identifier. * \note All data can be cleared with ClearDiagram() * \throws Invalid Argument Exception when the label cannot be found */ void RemoveData(const std::string& label); void UpdateLabel(const std::string& existingLabel, const std::string& newLabel); QmitkChartxyData *GetDataElementByLabel(const std::string& label) const; /*! * \brief Sets the color of one data entry (identifier is previously assigned label) * \details the color name can be "red" or a hex number (#FF0000). * \warning Either define all data entries with a color or no data entry. If a mixed approach is used, * plotly choses the color of the data entry (that could be the same as a user defined color). * \note If an unknown label is given, nothing happens. * \sa https://www.w3schools.com/cssref/css_colors.asp */ void SetColor(const std::string& label, const std::string& colorName); /*! * \brief Sets the line style of one data entry (identifier is previously assigned label) * \details two line styles are possible: LineStyle::solid and LineStyle::dashed. * The default line style is solid. * \note If an unknown label is given, nothing happens. * \warning only sets the line style if the current chart type is ChartType::line. * However, the line style remains also if the chart changes (e.g. new chart type) */ void SetLineStyle(const std::string& label, LineStyle style); /*! * \brief Sets the marker style of one data entry (identifier is previously assigned label) * \note If an unknown label is given, nothing happens. */ void SetMarkerSymbol(const std::string &label, MarkerSymbol symbol); /*! * \brief Sets the axis scale to either linear (default) or logarithmic. * \sa https://plot.ly/javascript/log-plot/ */ void SetYAxisScale(AxisScale scale); void SetXAxisLabel(const std::string& label); void SetYAxisLabel(const std::string& label); /*! * \brief Sets labels for pie chart data. * \note in AddData1D, the label still has to be given that acts as a unique id. However, the label is omitted then. */ void SetPieLabels(const std::vector &pieLabels, const std::string &label); /*! * \brief Sets a title for the chart. */ void SetTitle(const std::string &title); /*! * \brief Sets the chart type for a data entry * \details for available types, see ChartType * \note If an unknown label is given, nothing happens. * \warning Pie chart is significantly different than the other chart types. Here, the data given by AddData1D is summed. Each entry represents a different category. * \sa DiagramType for available types */ void SetChartType(const std::string& label, ChartType type); /*! * \brief Sets error bars for data in x direction * \note If only error plus is provided, the error bars are symmetrical * \param label the name of the data that is also used as identifier. * \param errorPlus the error in positive direction * \param errorMinus the error in negative direction. Same as error plus if omitted */ void SetXErrorBars(const std::string &label, const std::vector &errorPlus, const std::vector& errorMinus = std::vector()); /*! * \brief Sets error bars for data in y direction * \details for parameters, see SetXErrorBars * \note If only error plus is provided, the error bars are symmetrical */ void SetYErrorBars(const std::string &label, const std::vector &errorPlus, const std::vector &errorMinus = std::vector()); /*! * \brief Sets the legend position. * \details Default position is bottom. * \sa LegendPosition for available types */ void SetLegendPosition(LegendPosition position); void SetShowLegend(bool show); void SetStackedData(bool stacked); /*! * \brief Displays the chart in the widget * \param showSubChart if a subchart is displayed inside the widget or not. * \note if no data has been provided, (\sa AddData1D AddData2D), an empty chart is displayed. */ void Show(bool showSubChart=false); /*! * \brief Either displays the dataPoints or not * \param showDataPoints if dataPoints are displayed inside the widget or not. * \details: example for not showing points: https://plot.ly/javascript/line-charts/#styling-line-plot * example for showing the points: https://plot.ly/javascript/pointcloud/ */ void SetShowDataPoints(bool showDataPoints); /*! * \brief Clears all data inside and resets the widget. */ void Clear(); /*! * \brief Sets the theme of the widget. * \details default is dark theme as in MITK. * \warning has to be called before Show() or Reload() to work */ void SetTheme(ColorTheme themeEnabled); /*! * \brief Sets whether the subchart shall be shown. * \details Changes the state of the current chart object. * \note Needs to be reloaded with Reload() to display changes. */ void SetShowSubchart(bool showSubChart); /*! * \brief Sets whether the error bars shall be shown. * \details Changes the state of the current chart object. * \note Needs to be reloaded with Reload() to display changes. * \param showErrorBars if error bars are displayed or not. */ void SetShowErrorBars(bool showErrorBars); /*! * \brief Sets the min and max x values of the chart * \details Zooms in to view the values between minValue and maxValue in x direction */ void SetMinMaxValueXView(double minValueX,double maxValueX); /*! * \brief Sets the min and max y values of the chart * \details Zooms in to view the values between minValue and maxValue in y direction */ void SetMinMaxValueYView(double minValueY, double maxValueY); /*! * \brief Reloads the chart in the widget * \details reloading may be needed to display added data in an existing chart */ void Reload(); QSize sizeHint() const override; void SavePlotAsImage(); public slots: void OnLoadFinished(bool isLoadSuccessful); void OnPageSuccessfullyLoaded(); signals: void PageSuccessfullyLoaded(); private: /*! source: https://stackoverflow.com/questions/29383/converting-bool-to-text-in-c*/ std::string convertBooleanValue(bool value) const; class Impl; std::unique_ptr m_Impl; }; #endif diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp index f06b177119..775e7427a5 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.cpp @@ -1,197 +1,220 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkHistogramVisualizationWidget.h" #include QmitkHistogramVisualizationWidget::QmitkHistogramVisualizationWidget(QWidget* parent) : QWidget(parent) { - m_Controls.setupUi(this); + m_Controls.setupUi(this); m_Controls.checkBoxShowSubchart->setChecked(false); m_Controls.spinBoxNBins->setValue(m_DefaultNBins); m_Controls.spinBoxNBins->setMinimum(m_MinNBins); m_Controls.spinBoxNBins->setMaximum(m_MaxNBins); + m_Controls.chartWidget->SetXAxisLabel("Gray value"); + m_Controls.chartWidget->SetYAxisLabel("Frequency"); + SetGUIElementsEnabled(false); CreateConnections(); } void QmitkHistogramVisualizationWidget::SetHistogram(itk::Statistics::Histogram::ConstPointer histogram, const std::string& dataLabel) { - if (histogram == nullptr) - return; - - m_Histogram = histogram; - m_Controls.chartWidget->AddData2D(ConvertHistogramToPairList(m_Histogram), dataLabel); - m_Controls.chartWidget->SetChartType(dataLabel, QmitkChartWidget::ChartType::bar); - m_Controls.chartWidget->SetXAxisLabel("Gray value"); - m_Controls.chartWidget->SetYAxisLabel("Frequency"); + if (histogram == nullptr) + return; + + if (m_Histograms.find(dataLabel) == m_Histograms.end()) + { + m_Histograms.insert(std::make_pair(dataLabel, histogram)); + m_Controls.chartWidget->AddData2D(ConvertHistogramToPairList(histogram), dataLabel); + } + else + { + m_Histograms[dataLabel] = histogram; + m_Controls.chartWidget->UpdateData2D(ConvertHistogramToPairList(histogram), dataLabel); + } + m_Controls.chartWidget->SetChartType(dataLabel, QmitkChartWidget::ChartType::bar); + m_Controls.chartWidget->Show(m_Controls.checkBoxShowSubchart->isChecked()); - SetGUIElementsEnabled(true); + + SetGUIElementsEnabled(!m_Histograms.empty()); } void QmitkHistogramVisualizationWidget::Reset() { - m_Controls.chartWidget->Clear(); - SetGUIElementsEnabled(false); + m_Controls.chartWidget->Clear(); + SetGUIElementsEnabled(false); } int QmitkHistogramVisualizationWidget::GetBins() { return m_Controls.spinBoxNBins->value(); } void QmitkHistogramVisualizationWidget::ResetDefault() { m_Controls.checkBoxUseDefaultNBins->setChecked(true); m_Controls.spinBoxNBins->setEnabled(false); m_Controls.spinBoxNBins->setValue(100); m_Controls.checkBoxShowSubchart->setChecked(false); } void QmitkHistogramVisualizationWidget::SetTheme(QmitkChartWidget::ColorTheme style) { m_Controls.chartWidget->SetTheme(style); } void QmitkHistogramVisualizationWidget::CreateConnections() { - connect(m_Controls.buttonCopyHistogramToClipboard, &QPushButton::clicked, this, &QmitkHistogramVisualizationWidget::OnClipboardButtonClicked); - connect(m_Controls.checkBoxUseDefaultNBins, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnDefaultNBinsCheckBoxChanged); - connect(m_Controls.spinBoxNBins, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnNBinsSpinBoxValueChanged); - connect(m_Controls.checkBoxShowSubchart, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnShowSubchartCheckBoxChanged); - connect(m_Controls.checkBoxViewMinMax, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnViewMinMaxCheckBoxChanged); - connect(m_Controls.doubleSpinBoxMaxValue, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnMaxValueSpinBoxValueChanged); - connect(m_Controls.doubleSpinBoxMinValue, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnMinValueSpinBoxValueChanged); + connect(m_Controls.buttonCopyHistogramToClipboard, &QPushButton::clicked, this, &QmitkHistogramVisualizationWidget::OnClipboardButtonClicked); + connect(m_Controls.checkBoxUseDefaultNBins, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnDefaultNBinsCheckBoxChanged); + connect(m_Controls.spinBoxNBins, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnNBinsSpinBoxValueChanged); + connect(m_Controls.checkBoxShowSubchart, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnShowSubchartCheckBoxChanged); + connect(m_Controls.checkBoxViewMinMax, &QCheckBox::clicked, this, &QmitkHistogramVisualizationWidget::OnViewMinMaxCheckBoxChanged); + connect(m_Controls.doubleSpinBoxMaxValue, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnMaxValueSpinBoxValueChanged); + connect(m_Controls.doubleSpinBoxMinValue, &QSpinBox::editingFinished, this, &QmitkHistogramVisualizationWidget::OnMinValueSpinBoxValueChanged); } void QmitkHistogramVisualizationWidget::SetGUIElementsEnabled(bool enabled) { - this->setEnabled(enabled); - m_Controls.tabWidgetPlot->setEnabled(enabled); - m_Controls.checkBoxShowSubchart->setEnabled(enabled); - m_Controls.checkBoxUseDefaultNBins->setEnabled(enabled); - m_Controls.spinBoxNBins->setEnabled(!m_Controls.checkBoxUseDefaultNBins->isChecked()); - m_Controls.buttonCopyHistogramToClipboard->setEnabled(enabled); - m_Controls.checkBoxViewMinMax->setEnabled(enabled); - m_Controls.doubleSpinBoxMaxValue->setEnabled(m_Controls.checkBoxViewMinMax->isChecked()); - m_Controls.doubleSpinBoxMinValue->setEnabled(m_Controls.checkBoxViewMinMax->isChecked()); + this->setEnabled(enabled); + m_Controls.tabWidgetPlot->setEnabled(enabled); + m_Controls.checkBoxShowSubchart->setEnabled(enabled); + m_Controls.checkBoxUseDefaultNBins->setEnabled(enabled); + m_Controls.spinBoxNBins->setEnabled(!m_Controls.checkBoxUseDefaultNBins->isChecked()); + m_Controls.buttonCopyHistogramToClipboard->setEnabled(enabled); + m_Controls.checkBoxViewMinMax->setEnabled(enabled); + m_Controls.doubleSpinBoxMaxValue->setEnabled(m_Controls.checkBoxViewMinMax->isChecked()); + m_Controls.doubleSpinBoxMinValue->setEnabled(m_Controls.checkBoxViewMinMax->isChecked()); } std::vector< std::pair > QmitkHistogramVisualizationWidget::ConvertHistogramToPairList(itk::Statistics::Histogram::ConstPointer histogram) const { std::map histogramMap; - if (histogram) - { - auto endIt = histogram->End(); - auto it = histogram->Begin(); - - // generating Lists of measurement and frequencies - for (; it != endIt; ++it) - { - double frequency = it.GetFrequency(); - double measurement = it.GetMeasurementVector()[0]; - histogramMap.emplace(measurement, frequency); - } - - } + if (histogram) + { + auto endIt = histogram->End(); + auto it = histogram->Begin(); + + // generating Lists of measurement and frequencies + for (; it != endIt; ++it) + { + double frequency = it.GetFrequency(); + double measurement = it.GetMeasurementVector()[0]; + histogramMap.emplace(measurement, frequency); + } + + } std::vector< std::pair > histogram_list; for(auto iter = histogramMap.begin(); iter != histogramMap.end(); ++iter) histogram_list.emplace_back( iter->first, iter->second ); return histogram_list; } void QmitkHistogramVisualizationWidget::OnClipboardButtonClicked() { - if (m_Histogram) + if (!m_Histograms.empty()) { - QString clipboard("Measurement \t Frequency\n"); - auto iter = m_Histogram->Begin(); - auto iterEnd = m_Histogram->End(); - for (; iter != iterEnd; ++iter) + QString clipboard; + for (const auto& histogram : m_Histograms) { - clipboard = clipboard.append("%L1 \t %L2\n") - .arg(iter.GetMeasurementVector()[0], 0, 'f', 2) - .arg(iter.GetFrequency()); + clipboard.append(QString::fromStdString(histogram.first)); + clipboard.append("Measurement \t Frequency\n"); + auto iter = histogram.second->Begin(); + auto iterEnd = histogram.second->End(); + for (; iter != iterEnd; ++iter) + { + clipboard = clipboard.append("%L1 \t %L2\n") + .arg(iter.GetMeasurementVector()[0], 0, 'f', 2) + .arg(iter.GetFrequency()); + } + clipboard.append("\n\n"); } QApplication::clipboard()->clear(); QApplication::clipboard()->setText(clipboard, QClipboard::Clipboard); } } void QmitkHistogramVisualizationWidget::OnDefaultNBinsCheckBoxChanged() { - if (m_Controls.checkBoxUseDefaultNBins->isChecked()) - { - m_Controls.spinBoxNBins->setEnabled(false); + if (m_Controls.checkBoxUseDefaultNBins->isChecked()) + { + m_Controls.spinBoxNBins->setEnabled(false); if (m_Controls.spinBoxNBins->value() != static_cast(m_DefaultNBins) ) { m_Controls.spinBoxNBins->setValue(m_DefaultNBins); OnNBinsSpinBoxValueChanged(); } - } - else - { - m_Controls.spinBoxNBins->setEnabled(true); - } + } + else + { + m_Controls.spinBoxNBins->setEnabled(true); + } } void QmitkHistogramVisualizationWidget::OnNBinsSpinBoxValueChanged() { - emit RequestHistogramUpdate(m_Controls.spinBoxNBins->value()); + emit RequestHistogramUpdate(m_Controls.spinBoxNBins->value()); } void QmitkHistogramVisualizationWidget::OnShowSubchartCheckBoxChanged() { - m_Controls.chartWidget->Show(m_Controls.checkBoxShowSubchart->isChecked()); + m_Controls.chartWidget->Show(m_Controls.checkBoxShowSubchart->isChecked()); } void QmitkHistogramVisualizationWidget::OnViewMinMaxCheckBoxChanged() { - double min = m_Histogram->GetBinMin(0, 0); - auto maxVector = m_Histogram->GetDimensionMaxs(0); - double max; - if (m_Controls.checkBoxUseDefaultNBins->isChecked()) - max = maxVector[m_DefaultNBins - 1]; - else - max = maxVector[m_Controls.spinBoxNBins->value() - 1]; - - if (!m_Controls.checkBoxViewMinMax->isChecked()) - { - m_Controls.doubleSpinBoxMaxValue->setEnabled(false); - m_Controls.doubleSpinBoxMinValue->setEnabled(false); - m_Controls.chartWidget->Reload(); - } - else - { - m_Controls.doubleSpinBoxMinValue->setMinimum(min); + double min = itk::NumericTraits::max(); + double max = itk::NumericTraits::NonpositiveMin(); + for (const auto& histogram : m_Histograms) + { + auto aMin = histogram.second->GetBinMin(0, 0); + if (min > aMin) min = aMin; + + auto maxVector = histogram.second->GetDimensionMaxs(0); + if (m_Controls.checkBoxUseDefaultNBins->isChecked()) + if (max < maxVector[m_DefaultNBins - 1]) max = maxVector[m_DefaultNBins - 1]; + else + if (max < maxVector[m_Controls.spinBoxNBins->value() - 1]) max = maxVector[m_Controls.spinBoxNBins->value() - 1]; + } + + if (!m_Controls.checkBoxViewMinMax->isChecked()) + { + m_Controls.doubleSpinBoxMaxValue->setEnabled(false); + m_Controls.doubleSpinBoxMinValue->setEnabled(false); + m_Controls.chartWidget->Reload(); + } + else + { + m_Controls.doubleSpinBoxMinValue->setMinimum(min); m_Controls.doubleSpinBoxMinValue->setValue(min); - m_Controls.doubleSpinBoxMaxValue->setMaximum(max); + m_Controls.doubleSpinBoxMaxValue->setMaximum(max); m_Controls.doubleSpinBoxMaxValue->setValue(max); - m_Controls.doubleSpinBoxMaxValue->setEnabled(true); - m_Controls.doubleSpinBoxMinValue->setEnabled(true); - } + m_Controls.doubleSpinBoxMaxValue->setEnabled(true); + m_Controls.doubleSpinBoxMinValue->setEnabled(true); + } } void QmitkHistogramVisualizationWidget::OnMinValueSpinBoxValueChanged() { - m_Controls.doubleSpinBoxMaxValue->setMinimum(m_Controls.doubleSpinBoxMinValue->value()+1); + m_Controls.doubleSpinBoxMaxValue->setMinimum(m_Controls.doubleSpinBoxMinValue->value()+1); m_Controls.chartWidget->SetMinMaxValueXView(m_Controls.doubleSpinBoxMinValue->value(),m_Controls.doubleSpinBoxMaxValue->value()); m_Controls.chartWidget->Show(); } void QmitkHistogramVisualizationWidget::OnMaxValueSpinBoxValueChanged() { - m_Controls.doubleSpinBoxMinValue->setMaximum(m_Controls.doubleSpinBoxMaxValue->value()-1); + m_Controls.doubleSpinBoxMinValue->setMaximum(m_Controls.doubleSpinBoxMaxValue->value()-1); m_Controls.chartWidget->SetMinMaxValueXView(m_Controls.doubleSpinBoxMinValue->value(),m_Controls.doubleSpinBoxMaxValue->value()); m_Controls.chartWidget->Show(); } diff --git a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.h b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.h index 67f5bbc990..3920daa1f8 100644 --- a/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.h +++ b/Modules/ImageStatisticsUI/Qmitk/QmitkHistogramVisualizationWidget.h @@ -1,79 +1,79 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef QmitkHistogramVisualizationWidget_H__INCLUDED #define QmitkHistogramVisualizationWidget_H__INCLUDED #include #include // itk #include /** * \brief Widget for displaying Histograms. */ class MITKIMAGESTATISTICSUI_EXPORT QmitkHistogramVisualizationWidget : public QWidget { Q_OBJECT public: QmitkHistogramVisualizationWidget(QWidget *parent = nullptr); /** \brief Draws the histogram and enables the GUI elements. */ void SetHistogram(itk::Statistics::Histogram::ConstPointer histogram, const std::string &dataLabel); /** \brief Clears the histogram and disables all GUI elements. */ void Reset(); /** \brief Sets the theme (either dark or light) */ void SetTheme(QmitkChartWidget::ColorTheme style); /** \brief Resets the default settings */ void ResetDefault(); /** \brief Gets the number of bins to calculate */ int GetBins(); signals: /** \brief Signal to be emitted when the number of bins is changed by the user. The HistogramCalculator should connect to this signal and recalculate the data accordingly. */ void RequestHistogramUpdate(unsigned int nBins); private: void CreateConnections(); void SetGUIElementsEnabled(bool enabled); /** \brief Helper function to convert the histogram in order to forward it to the ChartWidget. */ std::vector > ConvertHistogramToPairList(itk::Statistics::Histogram::ConstPointer histogram) const; //slots /** \brief Saves the histogram to the clipboard. */ void OnClipboardButtonClicked(); /** \brief Enables / Disables SpinBox to change the number of bins. */ void OnDefaultNBinsCheckBoxChanged(); /** \brief Emits the signal RequestHistogramUpdate(unsigned int nBins) with the updated value. */ void OnNBinsSpinBoxValueChanged(); /** \brief Shows / Hides the subchart. */ void OnShowSubchartCheckBoxChanged(); /** \brief Enables / Disables SpinBoxes to set custom min and max values */ void OnViewMinMaxCheckBoxChanged(); /**\brief */ void OnMaxValueSpinBoxValueChanged(); /** \brief */ void OnMinValueSpinBoxValueChanged(); private: Ui::QmitkHistogramVisualizationControls m_Controls; const unsigned int m_DefaultNBins = 100; const unsigned int m_MinNBins = 10; const unsigned int m_MaxNBins = 10000; - itk::Statistics::Histogram::ConstPointer m_Histogram; + std::map < std::string, itk::Statistics::Histogram::ConstPointer> m_Histograms; }; #endif // QmitkHistogramVisualizationWidget_H__INCLUDED