diff --git a/Modules/Chart/include/QmitkChartData.h b/Modules/Chart/include/QmitkChartData.h index 6c97184762..e50b3bc26a 100644 --- a/Modules/Chart/include/QmitkChartData.h +++ b/Modules/Chart/include/QmitkChartData.h @@ -1,81 +1,92 @@ /*=================================================================== 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 QmitkC3Data_h #define QmitkC3Data_h #include #include /** \brief This class holds the relevant properties for the chart generation with C3 such as labels and diagram type. * It is derived from QObject, because we need Q_PROPERTIES to send Data via QWebChannel to JavaScript. * \sa The actual data for the chart generation is in QmitkC3xyData! */ class QmitkChartData : public QObject { Q_OBJECT Q_PROPERTY(QList m_dataLabels READ GetDataLabels WRITE SetDataLabels NOTIFY SignalDataLabelsChanged); Q_PROPERTY(QVariant m_xAxisLabel READ GetXAxisLabel WRITE SetXAxisLabel NOTIFY SignalXAxisLabelChanged); Q_PROPERTY(QVariant m_yAxisLabel READ GetYAxisLabel WRITE SetYAxisLabel NOTIFY SignalYAxisLabelChanged); + Q_PROPERTY(QVariant m_diagramTitle READ GetDiagramTitle WRITE SetDiagramTitle NOTIFY SignalDiagramTitleChanged); Q_PROPERTY(QVariant m_DiagramTypeName READ GetDiagramType WRITE SetDiagramType NOTIFY SignalDiagramTypeChanged); + Q_PROPERTY(QVariant m_LegendPosition READ GetLegendPosition WRITE SetLegendPosition NOTIFY SignalLegendPositionChanged); Q_PROPERTY(QVariant m_ShowSubchart READ GetShowSubchart WRITE SetShowSubchart NOTIFY SignalShowSubchartChanged); Q_PROPERTY(QVariant m_UsePercentageInPieChart READ GetUsePercentageInPieChart WRITE SetUsePercentageInPieChart NOTIFY SignalUsePercentageInPieChartChanged); public: QmitkChartData(); void SetAppearance(const QVariant& diagramTypeName, bool showSubChart = true, bool usePercentageInPieChart = false); Q_INVOKABLE QList GetDataLabels() const { return m_dataLabels; }; Q_INVOKABLE void SetDataLabels(const QList& dataLabels) { m_dataLabels = dataLabels; emit SignalDataLabelsChanged(dataLabels); }; Q_INVOKABLE QVariant GetXAxisLabel() const { return m_xAxisLabel; }; Q_INVOKABLE void SetXAxisLabel(const QVariant& label) { m_xAxisLabel = label; emit SignalXAxisLabelChanged(label); }; Q_INVOKABLE QVariant GetYAxisLabel() const { return m_yAxisLabel; }; Q_INVOKABLE void SetYAxisLabel(const QVariant& label) { m_yAxisLabel = label; emit SignalYAxisLabelChanged(label); }; + Q_INVOKABLE QVariant GetDiagramTitle() const { return m_diagramTitle; }; + Q_INVOKABLE void SetDiagramTitle(const QVariant& title) { m_diagramTitle = title; emit SignalDiagramTitleChanged(title); }; + Q_INVOKABLE QVariant GetDiagramType() const { return m_DiagramTypeName; }; Q_INVOKABLE void SetDiagramType(const QVariant& diagramTypeName) { m_DiagramTypeName = diagramTypeName; emit SignalDiagramTypeChanged(diagramTypeName); }; + Q_INVOKABLE QVariant GetLegendPosition() const { return m_LegendPosition; }; + Q_INVOKABLE void SetLegendPosition(const QVariant& legendPosition) { m_LegendPosition = legendPosition; emit SignalLegendPositionChanged(legendPosition); }; + Q_INVOKABLE QVariant GetShowSubchart() const { return m_ShowSubchart; }; Q_INVOKABLE void SetShowSubchart(const QVariant& showSubchart) { m_ShowSubchart = showSubchart; emit SignalShowSubchartChanged(showSubchart); }; Q_INVOKABLE QVariant GetUsePercentageInPieChart() const { return m_UsePercentageInPieChart; }; Q_INVOKABLE void SetUsePercentageInPieChart(const QVariant& usePercentageInPieChart) { m_UsePercentageInPieChart = usePercentageInPieChart; emit SignalUsePercentageInPieChartChanged(usePercentageInPieChart); }; signals: void SignalDataLabelsChanged(const QList dataLabels); void SignalYAxisLabelChanged(const QVariant label); void SignalXAxisLabelChanged(const QVariant label); void SignalDiagramTypeChanged(const QVariant chartType); + void SignalLegendPositionChanged(const QVariant legendPosition); + void SignalDiagramTitleChanged(const QVariant title); void SignalShowSubchartChanged(const QVariant showSubchart); void SignalUsePercentageInPieChartChanged(const QVariant usePercentageInPieChart); private: QList m_dataLabels; QVariant m_xAxisLabel; QVariant m_yAxisLabel; QVariant m_diagramTitle; QVariant m_DiagramTypeName; + QVariant m_LegendPosition; QVariant m_ShowSubchart; QVariant m_UsePercentageInPieChart; QVariant m_numberDatasets; }; #endif //QmitkC3Data_h \ No newline at end of file diff --git a/Modules/Chart/include/QmitkChartWidget.h b/Modules/Chart/include/QmitkChartWidget.h index 50120525e8..570182c9c5 100644 --- a/Modules/Chart/include/QmitkChartWidget.h +++ b/Modules/Chart/include/QmitkChartWidget.h @@ -1,136 +1,152 @@ /*=================================================================== 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 QmitkC3jsWidget_h #define QmitkC3jsWidget_h #include #include #include /*! \brief QmitkChartWidget is a widget to display various charts based on the javascript chart library C3js. Currently, bar charts, line charts and pie charts are supported. * \details Data is added via AddData1D() or AddData2D().\n * There can be multiple charts (of the same type) created by calling AddData1D or AddData2D multiple times.\n\n * The following chart types are supported: * * line chart: http://c3js.org/samples/simple_multiple.html * * bar chart: http://c3js.org/samples/chart_bar.html * * spline chart: http://c3js.org/samples/chart_spline.html * * pie chart: http://c3js.org/samples/chart_pie.html * \n Technical details: The javascript code is embedded in a QWebEngineView. The actual js code is implemented in resource\Chart.js. * \sa http://c3js.org for further information about the used javaScript library. * \warning Pie is significantly different than the other types. Here, the data given by AddData1D is summed. Each entry represents a different category. * \ingroup Modules/Chart */ class MITKCHART_EXPORT QmitkChartWidget : public QWidget { Q_OBJECT public: /*! * \brief enum of diagram types. Supported are bar, line, spline (a smoothed line) and pie. */ enum class ChartType { bar, /*!< bar chart, see http://c3js.org/samples/chart_bar.html */ line, /*!< line chart, see http://c3js.org/samples/simple_multiple.html */ spline, /*!< spline chart (smoothed line chart), see http://c3js.org/samples/chart_spline.html */ pie /*!< pie chart, see http://c3js.org/samples/chart_pie.html*/ }; enum class ChartStyle { defaultstyle, darkstyle }; + /*! + * \brief enum of legend position. Supported are bottom, right, inset. + * See http://c3js.org/reference.html#legend-position + */ + enum class LegendPosition { + bottom, + right, + inset + }; + explicit QmitkChartWidget(ChartType type=ChartType::bar, QWidget* parent = nullptr); virtual ~QmitkChartWidget(); /*! * \brief Adds 1D data to the widget * \details internally, the list is converted to a map with increasing integers keys starting at 0. * \note the data can be cleared with ClearDiagram() */ void AddData1D(const std::vector& data1D); /*! * \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. * \note the data can be cleared with ClearDiagram() */ void AddData2D(const std::map& data2D); /*! * \brief Sets the data labels as legend * \details Sets a label for each data entry (i.e. line). Default is data+#number */ void SetDataLabels(const std::vector& labels); std::vector GetDataLabels() const; void SetXAxisLabel(const std::string& label); std::string GetXAxisLabel() const; void SetYAxisLabel(const std::string& label); std::string GetYAxisLabel() const; + void SetDiagramTitle(const std::string &title); + std::string GetDiagramTitle() const; + /*! * \brief sets the diagram type * \note to also display the changes, call ChangeDiagramTypeAndReload() * \sa DiagramType for available types */ void SetChartType(ChartType type); ChartType GetChartType() const; + void SetLegendPosition(LegendPosition position); + LegendPosition GetLegendPosition() const; + /*! * \brief Reloads the chart and changes the chart type */ void SetChartTypeAndReload(ChartType type); /*! * \brief Displays the diagram in the widget * \param showSubChart if a subchart is displayed inside the widget or not. * \details see http://c3js.org/samples/options_subchart.html */ void Show(bool showSubChart=false); /*! * \brief Clears all data inside and resets the widget. */ void Clear(); /*! * \brief Changes the theme of the widget. */ void SetTheme(ChartStyle themeEnabled); /*! * \brief Reloads the chart in the widget * \details reloading may be needed to display added data in an existing chart * \param showSubChart if a subchart is displayed inside the widget or not. */ void Reload(bool showSubChart); private: class Impl; Impl* m_Impl; public slots: void OnLoadFinished(bool isLoadSuccessfull); signals: void PageSuccessfullyLoaded(); }; #endif diff --git a/Modules/Chart/resource/Chart.js b/Modules/Chart/resource/Chart.js index 30babd9167..c18f6f40b2 100644 --- a/Modules/Chart/resource/Chart.js +++ b/Modules/Chart/resource/Chart.js @@ -1,218 +1,224 @@ //Based on C3.js (http://c3js.org). See Website for examples! document.body.style.backgroundColor = 'rgb(240, 240, 240)'; var minHeight = 255; var chart; GenerateChart('bar', false, false) var chartData; var xValues=[]; var yValues=[]; var xs = {}; //Is executed when js is loaded first. //Extracts relevant information from chartData in variables window.onload = function() { new QWebChannel(qt.webChannelTransport, function(channel) { chartData = channel.objects.chartData; var count = 0; for(var propertyName in channel.objects) { if (propertyName != 'chartData'){ var xDataTemp = channel.objects[propertyName].m_XData var yDataTemp = channel.objects[propertyName].m_YData var dataLabelsTemp; //add label to x array xDataTemp.unshift('x'+count.toString()) if (count < chartData.m_dataLabels.length){ dataLabelsTemp = chartData.m_dataLabels[count] } else { dataLabelsTemp = "data" + count.toString() } xs[dataLabelsTemp] = 'x'+count.toString() xDataTemp.push(null); //append null value, to make sure the last tick on x-axis is displayed correctly yDataTemp.unshift(dataLabelsTemp) yDataTemp.push(null); //append null value, to make sure the last tick on y-axis is displayed correctly xValues[count] = xDataTemp yValues[count] = yDataTemp count++; } } setupChart(chartData) }); } //This is necessary to resize the chart, after the size of the parent changed window.onresize = function () { var size = window.innerHeight-(window.innerHeight/100*10); //subtract 5% of height to hide vertical scrool bar if (size < minHeight) { size = minHeight; } chart.resize({ height: size, }); } function ReloadChart(showSubchart) { chartData.m_ShowSubchart = showSubchart; setupChart(chartData); } function setupChart(chartData) { window.onresize(); - GenerateChart(chartData.m_DiagramTypeName, chartData.m_ShowSubchart, chartData.m_UsePercentageInPieChart, chartData.m_xAxisLabel, chartData.m_yAxisLabel) + GenerateChart(chartData.m_DiagramTypeName, chartData.m_ShowSubchart, chartData.m_UsePercentageInPieChart, + chartData.m_xAxisLabel, chartData.m_yAxisLabel, chartData.m_diagramTitle, chartData.m_LegendPosition) chart.unload(); //unload data before loading new data //for multiple xy line chart, see http://c3js.org/samples/simple_xy_multiple.html var columns = []; for (var i in xValues){ columns.push(xValues[i]) } for (var i in yValues){ columns.push(yValues[i]) } chart.load({ xs: xs, columns: columns }); } //Transformation between different chart types //takes the name of the chart type as a parameter //called by QmitkC3jsWidget function transformView(TransformTo) { chart.transform(TransformTo); }; function changeTheme(color) { if (color == 'dark') { link = document.getElementsByTagName("link")[0]; link.href = "Chart_dark.css"; } else { link = document.getElementsByTagName("link")[0]; link.href = "Chart.css"; } }; //Here, the chart magic takes place. C3js is called //chartType: either bar, line or pie //showSubchart: see http://c3js.org/samples/options_subchart.html //usePercentageInPieChart: percentage labels (only for pie chart) -function GenerateChart(chartType, showSubchart, usePercentageInPieChart, xAxisLabel, yAxisLabel) +function GenerateChart(chartType, showSubchart, usePercentageInPieChart, xAxisLabel, yAxisLabel, title, legendPosition) { //adaption for bar ratio indepenend of amount of data points //otherwise, bars could be covered. var barRatio; try { barRatio = 0.8*Math.exp(-0.015*xValues[0].length); } catch (err){ barRatio=0.42 } var formatCharacter; if (usePercentageInPieChart==true){ formatCharacter = '%' } else{ formatCharacter = 's' } chart = c3.generate({ + title:{ + text: title, + position: 'top-center' + }, data: { xs: {}, //use first "column" as x axis values columns: [], //initialize empty. Data will be loaded in function setupChart(chartData) type: chartType, selection: { enabled: false, multiple: false, } }, legend: { - position: 'bottom' + position: legendPosition, + show: true }, grid: { y: { lines: [{value:0}] //Draws a horizontal line at y=0 } }, bar: { width: { ratio: barRatio } }, pie:{ label: { format: function (value, ratio, id) { if (usePercentageInPieChart==true){ return d3.format('%') (ratio); } else{ return value; } } } }, zoom: { enabled: true, }, subchart: { show: showSubchart //Shows a subchart that shows the region the primary chart is zoomed in to by overlay. }, axis: { x: { tick: { multiline: false, fit: false, //to make more x labels appear on zoom centered: true, format: d3.format(".1f"), }, label: { text: xAxisLabel, position: 'outer-center' } }, y: { tick: { format: d3.format(formatCharacter) }, label: { text: yAxisLabel, position: 'outer-middle' } } }, tooltip: { format: { title: function (x) { return xAxisLabel + ': ' + d3.format(".2f")(x)} }, }, //Style data points in linegraph point: { r: 0.2, focus: { expand: { r: 4 } } }, }); } diff --git a/Modules/Chart/src/QmitkChartWidget.cpp b/Modules/Chart/src/QmitkChartWidget.cpp index c5841c4f0c..11a1bcb8c9 100644 --- a/Modules/Chart/src/QmitkChartWidget.cpp +++ b/Modules/Chart/src/QmitkChartWidget.cpp @@ -1,323 +1,381 @@ /*=================================================================== 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. ===================================================================*/ #include #include #include #include #include #include #include "mitkExceptionMacro.h" class QmitkChartWidget::Impl final { public: explicit Impl(QWidget* parent); ~Impl(); Impl(const Impl&) = delete; Impl& operator=(const Impl&) = delete; void AddData1D(const std::vector& data1D); void AddData2D(const std::map& data2D); void ClearData2D(); void SetDataLabels(const std::vector& labels); - std::vector GetDataLabels() const; void SetXAxisLabel(const std::string& label); std::string GetXAxisLabel() const; void SetYAxisLabel(const std::string& label); std::string GetYAxisLabel() const; + void SetDiagramTitle(const std::string &title); + std::string GetDiagramTitle() const; + + void SetLegendPosition(LegendPosition position); + LegendPosition GetLegendPosition() const; + std::string GetLegendPositionAsString() const; + void SetDiagramType(QmitkChartWidget::ChartType diagramType); ChartType GetDiagramType() const; std::string GetDiagramTypeAsString() const; void ClearJavaScriptChart(); void initializeJavaScriptChart(); void callJavaScriptFuntion(const QString& command); QmitkChartData* GetC3Data() const; std::vector* GetC3xyData() const; private: QWebChannel* m_WebChannel; QWebEngineView* m_WebEngineView; QmitkChartData * m_C3Data; std::vector * m_C3xyData; std::map m_DiagramTypeToName; + std::map m_LegendPositionToName; }; QmitkChartWidget::Impl::Impl(QWidget* parent) : m_WebChannel(new QWebChannel(parent)), m_WebEngineView(new QWebEngineView(parent)) { //disable context menu for QWebEngineView m_WebEngineView->setContextMenuPolicy(Qt::NoContextMenu); //Set the webengineview to an initial empty page. The actual chart will be loaded once the data is calculated. m_WebEngineView->setUrl(QUrl(QStringLiteral("qrc:///C3js/empty.html"))); m_WebEngineView->page()->setWebChannel(m_WebChannel); connect(m_WebEngineView, SIGNAL(loadFinished(bool)), parent, SLOT(OnLoadFinished(bool))); auto layout = new QGridLayout(parent); layout->setMargin(0); layout->addWidget(m_WebEngineView); parent->setLayout(layout); m_DiagramTypeToName.emplace(ChartType::bar, "bar"); m_DiagramTypeToName.emplace(ChartType::line, "line"); m_DiagramTypeToName.emplace(ChartType::spline, "spline"); m_DiagramTypeToName.emplace(ChartType::pie, "pie"); + m_LegendPositionToName.emplace(LegendPosition::bottom, "bottom"); + m_LegendPositionToName.emplace(LegendPosition::right, "right"); + m_LegendPositionToName.emplace(LegendPosition::inset, "inset"); + m_C3Data = new QmitkChartData(); m_C3xyData = new std::vector(); } QmitkChartWidget::Impl::~Impl() { delete m_C3Data; delete m_C3xyData; } void QmitkChartWidget::Impl::SetDataLabels(const std::vector& labels) { QList variantList; for (const auto& label : labels) { variantList.append(QString::fromStdString(label)); } GetC3Data()->SetDataLabels(variantList); } void QmitkChartWidget::Impl::AddData1D(const std::vector& data1D) { QList data1DConverted; for (const auto& aValue : data1D) { data1DConverted.append(aValue); } GetC3xyData()->push_back(new QmitkChartxyData(data1DConverted)); } void QmitkChartWidget::Impl::AddData2D(const std::map& data2D) { QMap data2DConverted; for (const auto& aValue : data2D) { data2DConverted.insert(aValue.first, aValue.second); } GetC3xyData()->push_back(new QmitkChartxyData(data2DConverted)); } std::vector QmitkChartWidget::Impl::GetDataLabels() const { auto dataLabels = GetC3Data()->GetDataLabels(); std::vector dataLabelsAsStringVector; for (const auto& label : dataLabels) { dataLabelsAsStringVector.push_back(label.toString().toStdString()); } return dataLabelsAsStringVector; } void QmitkChartWidget::Impl::SetXAxisLabel(const std::string& label) { GetC3Data()->SetXAxisLabel(QString::fromStdString(label)); } std::string QmitkChartWidget::Impl::GetXAxisLabel() const { return GetC3Data()->GetXAxisLabel().toString().toStdString(); } void QmitkChartWidget::Impl::SetYAxisLabel(const std::string& label) { GetC3Data()->SetYAxisLabel(QString::fromStdString(label)); } std::string QmitkChartWidget::Impl::GetYAxisLabel() const { return GetC3Data()->GetYAxisLabel().toString().toStdString(); } +void QmitkChartWidget::Impl::SetDiagramTitle(const std::string& title) { + GetC3Data()->SetDiagramTitle(QString::fromStdString(title)); +} + +std::string QmitkChartWidget::Impl::GetDiagramTitle() const { + return GetC3Data()->GetDiagramTitle().toString().toStdString(); +} + +void QmitkChartWidget::Impl::SetLegendPosition(QmitkChartWidget::LegendPosition legendPosition) { + const std::string legendPositionName(m_LegendPositionToName.at(legendPosition)); + GetC3Data()->SetLegendPosition(QString::fromStdString(legendPositionName)); +} + +QmitkChartWidget::LegendPosition QmitkChartWidget::Impl::GetLegendPosition() const { + for (const auto& aLegendPosition : m_LegendPositionToName) { + if (aLegendPosition.second == GetLegendPositionAsString()) { + return aLegendPosition.first; + } + } + mitkThrow() << "can't find legend position!"; +} + +std::string QmitkChartWidget::Impl::GetLegendPositionAsString() const { + return GetC3Data()->GetLegendPosition().toString().toStdString(); +} + + void QmitkChartWidget::Impl::SetDiagramType(QmitkChartWidget::ChartType diagramType) { const std::string diagramTypeName(m_DiagramTypeToName.at(diagramType)); GetC3Data()->SetDiagramType(QString::fromStdString(diagramTypeName)); } QmitkChartWidget::ChartType QmitkChartWidget::Impl::GetDiagramType() const { for (const auto& aDiagramType : m_DiagramTypeToName) { if (aDiagramType.second == GetDiagramTypeAsString()){ return aDiagramType.first; } } mitkThrow() << "can't find diagram type!"; } std::string QmitkChartWidget::Impl::GetDiagramTypeAsString() const { return GetC3Data()->GetDiagramType().toString().toStdString(); } QmitkChartData* QmitkChartWidget::Impl::GetC3Data() const { return m_C3Data; } std::vector* QmitkChartWidget::Impl::GetC3xyData() const { return m_C3xyData; } void QmitkChartWidget::Impl::ClearData2D() { GetC3xyData()->clear(); } QmitkChartWidget::QmitkChartWidget(ChartType type, QWidget* parent) : QWidget(parent), m_Impl(new Impl(this)) { SetChartType(type); } void QmitkChartWidget::Impl::callJavaScriptFuntion(const QString& command) { m_WebEngineView->page()->runJavaScript(command); } void QmitkChartWidget::Impl::ClearJavaScriptChart() { m_WebEngineView->setUrl(QUrl(QStringLiteral("qrc:///C3js/empty.html"))); } void QmitkChartWidget::Impl::initializeJavaScriptChart() { m_WebChannel->registerObject(QStringLiteral("chartData"), m_C3Data); unsigned count = 0; for (auto& xyData : *m_C3xyData) { QString variableName = "xyData" + QString::number(count); m_WebChannel->registerObject(variableName, xyData); count++; } m_WebEngineView->load(QUrl(QStringLiteral("qrc:///C3js/QmitkChartWidget.html"))); } QmitkChartWidget::~QmitkChartWidget() { delete m_Impl; } void QmitkChartWidget::AddData2D(const std::map& data2D) { m_Impl->AddData2D(data2D); } void QmitkChartWidget::AddData1D(const std::vector& data1D) { m_Impl->AddData1D(data1D); } void QmitkChartWidget::SetDataLabels(const std::vector& labels) { m_Impl->SetDataLabels(labels); } std::vector QmitkChartWidget::GetDataLabels() const { return m_Impl->GetDataLabels(); } void QmitkChartWidget::SetXAxisLabel(const std::string & label) { m_Impl->SetXAxisLabel(label); } std::string QmitkChartWidget::GetXAxisLabel() const { return m_Impl->GetXAxisLabel(); } void QmitkChartWidget::SetYAxisLabel(const std::string & label) { m_Impl->SetYAxisLabel(label); } std::string QmitkChartWidget::GetYAxisLabel() const { return m_Impl->GetYAxisLabel(); } +void QmitkChartWidget::SetDiagramTitle(const std::string & title) +{ + m_Impl->SetDiagramTitle(title); +} + +std::string QmitkChartWidget::GetDiagramTitle() const +{ + return m_Impl->GetDiagramTitle(); +} + void QmitkChartWidget::SetChartType(ChartType type) { m_Impl->SetDiagramType(type); } QmitkChartWidget::ChartType QmitkChartWidget::GetChartType() const { return m_Impl->GetDiagramType(); } +void QmitkChartWidget::SetLegendPosition(LegendPosition position) +{ + m_Impl->SetLegendPosition(position); +} + +QmitkChartWidget::LegendPosition QmitkChartWidget::GetLegendPosition() const +{ + return m_Impl->GetLegendPosition(); +} + void QmitkChartWidget::Show(bool showSubChart) { this->m_Impl->GetC3Data()->SetAppearance(m_Impl->GetC3Data()->GetDiagramType(), showSubChart, m_Impl->GetC3Data()->GetDiagramType()== QVariant("pie")); m_Impl->initializeJavaScriptChart(); } void QmitkChartWidget::Clear() { m_Impl->ClearData2D(); m_Impl->GetC3xyData()->clear(); m_Impl->ClearJavaScriptChart(); } void QmitkChartWidget::OnLoadFinished(bool isLoadSuccessfull) { if(isLoadSuccessfull) { emit PageSuccessfullyLoaded(); } } void QmitkChartWidget::SetChartTypeAndReload(ChartType type) { SetChartType(type); auto diagramTypeName = m_Impl->GetDiagramTypeAsString(); const QString command = QString::fromStdString("transformView('" + diagramTypeName + "')"); m_Impl->callJavaScriptFuntion(command); } void QmitkChartWidget::SetTheme(ChartStyle themeEnabled) { QString command; if (themeEnabled == ChartStyle::darkstyle) { command = QString("changeTheme('dark')"); } else { command = QString("changeTheme('default')"); } m_Impl->callJavaScriptFuntion(command); } void QmitkChartWidget::Reload(bool showSubChart) { QString subChartString; if (showSubChart) { subChartString = "true"; } else { subChartString = "false"; } const QString command = QString("ReloadChart(" + subChartString + ")"); m_Impl->callJavaScriptFuntion(command); }