diff --git a/Modules/QmitkExt/QmitkHistogramJSWidget.cpp b/Modules/QmitkExt/QmitkHistogramJSWidget.cpp index 8754651fa7..90adac052e 100644 --- a/Modules/QmitkExt/QmitkHistogramJSWidget.cpp +++ b/Modules/QmitkExt/QmitkHistogramJSWidget.cpp @@ -1,93 +1,97 @@ /*=================================================================== 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 "QmitkHistogramJSWidget.h" QmitkHistogramJSWidget::QmitkHistogramJSWidget(QWidget *parent) : QWebView(parent) { connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJSObject())); + connect(this, SIGNAL(loadFinished()), this, SLOT(resetData())); QUrl myUrl = QUrl("qrc:/qmitk/Histogram.html"); setUrl(myUrl); // set Scrollbars to always disabled page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); } QmitkHistogramJSWidget::~QmitkHistogramJSWidget() { } // adds an Object of Type QmitkHistogramJSWidget to the JavaScript void QmitkHistogramJSWidget::addJSObject() { page()->mainFrame()->addToJavaScriptWindowObject(QString("histogramData"), this); - this->clearData(); } // reloads WebView, everytime its size has been changed, so the size of the Histogram fits to the size of the widget void QmitkHistogramJSWidget::resizeEvent(QResizeEvent* resizeEvent) { QWebView::resizeEvent(resizeEvent); - this->sizeChanged(); + this->reload(); } void QmitkHistogramJSWidget::ComputeHistogram(HistogramType* histogram) { - //this->clearData(); m_Histogram = histogram; HistogramConstIteratorType startIt = m_Histogram->End(); HistogramConstIteratorType endIt = m_Histogram->End(); HistogramConstIteratorType it; m_Frequency.clear(); m_Measurement.clear(); unsigned int i = 0; for (it = m_Histogram->Begin() ; it != m_Histogram->End(); ++it, ++i) { QVariant frequency = it.GetFrequency(); QVariant measurement = it.GetMeasurementVector()[0]; m_Frequency.insert(i, frequency); m_Measurement.insert(i, measurement); } this->DataChanged(); } void QmitkHistogramJSWidget::clearData() { m_Frequency.clear(); m_Measurement.clear(); } void QmitkHistogramJSWidget::clearHistogram() { this->clearData(); this->DataChanged(); } QList QmitkHistogramJSWidget::getFrequency() { return m_Frequency; } QList QmitkHistogramJSWidget::getMeasurement() { return m_Measurement; } + +void QmitkHistogramJSWidget::resetData(bool ok) +{ + this->DataChanged(); +} diff --git a/Modules/QmitkExt/QmitkHistogramJSWidget.h b/Modules/QmitkExt/QmitkHistogramJSWidget.h index bcf77fef9a..aca421f45c 100644 --- a/Modules/QmitkExt/QmitkHistogramJSWidget.h +++ b/Modules/QmitkExt/QmitkHistogramJSWidget.h @@ -1,65 +1,66 @@ /*=================================================================== 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 QMITKHISTOGRAMJSWIDGET_H #define QMITKHISTOGRAMJSWIDGET_H #include #include #include #include "QmitkExtExports.h" #include #include "mitkImage.h" class QmitkExt_EXPORT QmitkHistogramJSWidget : public QWebView { Q_OBJECT Q_PROPERTY(QList measurement READ getMeasurement) Q_PROPERTY(QList frequency READ getFrequency) public: typedef mitk::Image::HistogramType HistogramType; typedef mitk::Image::HistogramType::ConstIterator HistogramConstIteratorType; explicit QmitkHistogramJSWidget(QWidget *parent = 0); ~QmitkHistogramJSWidget(); void resizeEvent(QResizeEvent* resizeEvent); void ComputeHistogram(HistogramType* histogram); void clearHistogram(); QList getMeasurement(); QList getFrequency(); private: QList m_Frequency; QList m_Measurement; HistogramType::ConstPointer m_Histogram; void clearData(); private slots: void addJSObject(); + void resetData(bool ok); signals: void DataChanged(); void sizeChanged(); }; #endif // QMITKHISTOGRAMJSWIDGET_H diff --git a/Modules/QmitkExt/resources/Histogram.js b/Modules/QmitkExt/resources/Histogram.js index 31c60ffeee..f7cc808483 100644 --- a/Modules/QmitkExt/resources/Histogram.js +++ b/Modules/QmitkExt/resources/Histogram.js @@ -1,202 +1,280 @@ /** * @author Moritz Petry */ //var dataset = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 18, 19, 22]; /*var indexNumber = Math.round(Math.random()*10+30); for (var i = 0; i< indexNumber; i++) { var newNumber = Math.random() * 100; dataset.push(newNumber); }*/ var dataset = new Array(); var frequency = new Array(); var measurement = new Array(); var dataset; var margin = { top : 30, bottom : 50, left : 50, right : 20, }; var height = histogramData.height - margin.top - margin.bottom; var width = histogramData.width - margin.left - margin.right; var tension = 0.8; var connected = false; var dur = 1000; +var useLinePlot = false; /* var line = d3.svg.line() .interpolate("cardinal") .x(function(d,i) { return xScale(histogramData.measurement[i]); }) .y(function(d,i) { return yScale(d); }) .tension(tension); var area = d3.svg.area() .interpolate("cardinal") .tension(tension) .x(function(d,i) { return xScale(histogramData.measurement[i]); }) .y0(height) .y1(function(d,i) { return yScale(d); }); */ if (!connected) { connected = true; - histogramData.DataChanged.connect(changeHistogram); + histogramData.DataChanged.connect(linePlot); histogramData.sizeChanged.connect(changeSize); } var xScale = d3.scale.linear() - .domain([d3.min(histogramData.measurement), d3.max(histogramData.measurement)]) - .range([margin.left, width]); + .domain([d3.min(histogramData.measurement),d3.max(histogramData.measurement)]) + .range([margin.left,width]); var yScale = d3.scale.linear() - .domain([0, d3.max(histogramData.frequency)]) - .range([height, margin.top]); + .domain([0,d3.max(histogramData.frequency)]) + .range([height,margin.top]); var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom"); var yAxis = d3.svg.axis() .scale(yScale) .orient("left"); var svg = d3.select("body") .append("svg") .attr("class", "svg") .attr("width", width + margin.right + margin.left) .attr("height", height + margin.top + margin.bottom); // svg.append("path") // .attr("class", "area") // .attr("fill", "steelblue") // .attr("opacity", 0.5) // .attr("d", area(histogramData.frequency)); // svg.append("path") // .attr("class", "line") // .attr("fill", "none") // .attr("stroke", "black") // .attr("stroke-width", 1) // .attr("d", line(histogramData.frequency)); // var bar = svg.selectAll("rect") // .data(histogramData.frequency) // .enter() // .append("rect") // .attr("class", "bar") // .attr("x", function(d,i) { // return xScale(histogramData.measurement[i]); // }) // .attr("y", function(d,i) { // return yScale(d); // }) // .attr("width", 1) // .attr("height", function(d) { // return height - yScale(d); // }) // .attr("fill", "grey") // .attr("opacity", 0.5); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + 0 + "," + height + ")") .call(xAxis); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + margin.left + "," + 0 + ")") .call(yAxis); function changeSize () { height = histogramData.height - margin.top - margin.bottom; width = histogramData.width - margin.left - margin.right; svg = d3.select("body") .append("svg") .attr("class", "svg") .attr("width", width + margin.right + margin.left) .attr("height", height + margin.top + margin.bottom); changeHistogram(); } function changeHistogram() { xScale = d3.scale.linear() .domain([d3.min(histogramData.measurement),d3.max(histogramData.measurement)]) .range([margin.left,width]); yScale = d3.scale.linear() .domain([0,d3.max(histogramData.frequency)]) - .range([height,margin.bottom]); + .range([height,margin.top]); xAxis = d3.svg.axis() .scale(xScale) .ticks(5) .orient("bottom"); yAxis = d3.svg.axis() .scale(yScale) .orient("left"); var bar = svg.selectAll("rect").data(histogramData.frequency); bar.enter().append("rect") .attr("class", "bar") .attr("x", function(d,i) { return xScale(histogramData.measurement[i]); }) .attr("y", height) .attr("height", 0) .attr("width", (width/(histogramData.frequency.length + 1))) .transition().duration(dur) .attr("height", function(d) { - return (height-yScale(d)); + return (height - yScale(d)); }) .attr("width", (width/(histogramData.frequency.length + 1))) .attr("y", function(d) { - return yScale(d); - }); + return yScale(d); + }); bar.transition().duration(dur) .attr("x", function(d,i) { return xScale(histogramData.measurement[i]); }) .attr("y", function(d) { return yScale(d); }) .attr("height", function(d) { - return (height-yScale(d)); + return (height - yScale(d)); }) .attr("width", (width/(histogramData.frequency.length + 1))) bar.exit().transition().duration(dur) .attr("y", height) .attr("height", 0) .remove(); - svg.selectAll("g").transition().duration(dur).attr("opacity", 0).remove(); + svg.selectAll("g") + .transition() + .duration(dur) + .attr("opacity", 0) + .remove(); + svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + 0 + "," + height + ")") .transition().duration(dur) + .attr("opacity", 100) .call(xAxis); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + margin.left + "," + 0 + ")") - .transition() + .transition().duration(dur) + .attr("opacity", 100) .call(yAxis); } +function linePlot() +{ + xScale = d3.scale.linear() + .domain([d3.min(histogramData.measurement),d3.max(histogramData.measurement)]) + .range([margin.left,width]); + + yScale = d3.scale.linear() + .domain([0,d3.max(histogramData.frequency)]) + .range([height,margin.top]); + + xAxis = d3.svg.axis() + .scale(xScale) + .ticks(5) + .orient("bottom"); + + yAxis = d3.svg.axis() + .scale(yScale) + .orient("left"); + + var line = d3.svg.line() + .interpolate("linear") + .x(function(d,i) { + return xScale(histogramData.measurement[i]); + }) + .y(function(d) { + return yScale(d); + }); + + var linenull = d3.svg.line() + .interpolate("linear") + .x(function(d,i) { + return xScale(i); + }) + .y(function(d) { + return yScale(0); + }); + + svg.selectAll("path") + .data([histogramData.frequency]) + .enter() + .append("path") + .attr("class", "line") + .attr("d", linenull); + + svg.selectAll("path") + .data([histogramData.frequency]) + .transition() + .duration(dur) + .attr("d", line); + + svg.selectAll("g") + .transition() + .duration(dur) + .attr("opacity", 0) + .remove(); + + svg.append("g") + .attr("class", "axis") + .attr("transform", "translate(" + 0 + "," + height + ")") + .transition().duration(dur) + .attr("opacity", 100) + .call(xAxis); + + svg.append("g") + .attr("class", "axis") + .attr("transform", "translate(" + margin.left + "," + 0 + ")") + .transition().duration(dur) + .attr("opacity", 100) + .call(yAxis); +} diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui index 200e706073..fc80cad62e 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsViewControls.ui @@ -1,363 +1,365 @@ QmitkImageStatisticsViewControls true 0 0 465 800 Form 0 0 Mask: None 2 Qt::Horizontal 40 20 color: rgb(255, 0, 0); Error Message Qt::AutoText Ignore zero-valued voxels + + + + + 150 + 160 + + + + Histogram + + + false + + + + + + + 0 + + + 0 + + + + + Copy to Clipboard + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 1 + + + + + 0 + 0 + + + + + + + 0 + 0 + + + groupBox_3 + m_StatisticsTable + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + Statistics - 0 + 9 - 0 + 9 - 0 + 9 - + 0 0 100 175 16777215 170 Qt::ScrollBarAlwaysOff Qt::ScrollBarAsNeeded true true true Qt::DotLine true false false 80 true 80 false true - false + true false 25 25 false false Mean StdDev RMS Max Min N V (mm³) Component 1 0 0 Copy to Clipboard Qt::Horizontal 40 20 - - - - - 150 - 160 - - - - Histogram - - - false - - - - - - 0 - - - - - 0 - 0 - - - - - - - 0 - 0 - - - - - - - - - - - 0 - - - 0 - - - - - Copy to Clipboard - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - QmitkVtkHistogramWidget QWidget
QmitkVtkHistogramWidget.h
1
QmitkVtkLineProfileWidget QWidget
QmitkVtkLineProfileWidget.h
1
QmitkHistogramJSWidget QWidget
QmitkHistogramJSWidget.h
1