Skip to content

Commit

Permalink
adds y-axis scale to the histogram view (#4349)
Browse files Browse the repository at this point in the history
* added changelog entry

* added axis to histogram and smoothing histogram
* smoothing is done by reducing the intensity value into the range
  from 1 to 10 and then taking the logarithm of these values

* altered changelog entry

* Apply suggestions from code review

* extract line width constant into a variable
  • Loading branch information
MichaelBuessemeyer authored Dec 10, 2019
1 parent 18f48ba commit 649fbdb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.md).
[Commits](https://github.com/scalableminds/webknossos/compare/19.12.0...HEAD)

### Added
- Added a new way of sharing annotations. You can share your annotations with selected teams. These annotations appear in the Shared Annotations Tab in the dashboard.
- Added a scale to the y-axis of histograms to indicate the logarithmic representation. Additionally, small histogram values are smoothed out. [#4349](https://github.com/scalableminds/webknossos/pull/4349)
- Added a new way of sharing annotations. You can share your annotations with selected teams. These annotations appear in the Shared Annotations Tab in the dashboard. [#4304](https://github.com/scalableminds/webknossos/pull/4304)

### Changed
-
Expand Down
29 changes: 24 additions & 5 deletions frontend/javascripts/oxalis/view/settings/histogram_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,16 @@ class Histogram extends React.PureComponent<HistogramProps> {
const { min, max } = this.props;
const { min: minRange, max: maxRange, elementCounts } = histogram;
const rangeLength = maxRange - minRange;
this.drawYAxis(ctx);
ctx.fillStyle = `rgba(${color.join(",")}, 0.1)`;
ctx.strokeStyle = `rgba(${color.join(",")})`;
const downscaledData = elementCounts.map(value =>
value > 0 ? (Math.log(value) / Math.log(maxValue)) * canvasHeight : 0,
// Here we normalize all values to the interval of 0 - 9 and then add 1
// to gain an interval reaching from 1 - 10, since values between 0 and 1 would be negative, otherwise.
const downscalingFactor = 9 / maxValue;
const downscaledData = elementCounts.map(
value => Math.log10(downscalingFactor * value + 1) * canvasHeight,
);
const activeRegion = new Path2D();
ctx.beginPath();
ctx.moveTo(0, downscaledData[0]);
activeRegion.moveTo(((min - minRange) / rangeLength) * canvasWidth, 0);
for (let i = 0; i < downscaledData.length; i++) {
Expand All @@ -104,6 +107,22 @@ class Histogram extends React.PureComponent<HistogramProps> {
ctx.fill(activeRegion);
};

drawYAxis = (ctx: CanvasRenderingContext2D) => {
// Maximum value of the y axis is always 10. Therefore the axis is independent from any data.
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, canvasHeight);
const numberOfScaleLines = 5;
const lineWidth = 8;
const intervalSize = 2;
for (let interval = 1; interval <= numberOfScaleLines; interval++) {
// We use canvasHeight - 1 because else half of the top line would be cut off.
const lineHeight = Math.round(Math.log10(intervalSize * interval) * (canvasHeight - 1));
ctx.moveTo(0, lineHeight);
ctx.lineTo(lineWidth, lineHeight);
}
};

onThresholdChange = ([firstVal, secVal]: [number, number]) => {
const { layerName } = this.props;
if (firstVal < secVal) {
Expand All @@ -122,7 +141,7 @@ class Histogram extends React.PureComponent<HistogramProps> {
ref={ref => {
this.canvasRef = ref;
}}
width={300}
width={canvasWidth}
height={canvasHeight}
/>
<Slider
Expand All @@ -133,7 +152,7 @@ class Histogram extends React.PureComponent<HistogramProps> {
defaultValue={[minRange, maxRange]}
onChange={this.onThresholdChange}
onAfterChange={this.onThresholdChange}
style={{ width: 300, margin: 0, marginBottom: 18 }}
style={{ width: canvasWidth, margin: 0, marginBottom: 18 }}
step={(maxRange - minRange) / 255}
tipFormatter={val => roundTo(val, 2).toString()}
/>
Expand Down

0 comments on commit 649fbdb

Please sign in to comment.