Skip to content

Commit

Permalink
Merge pull request #142 from RhoInc/hoverlap
Browse files Browse the repository at this point in the history
Overlap tooltips
  • Loading branch information
jwildfire authored Aug 20, 2019
2 parents 234ae0e + 07bc523 commit 3b2e378
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 79 deletions.
96 changes: 62 additions & 34 deletions safetyOutlierExplorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2062,35 +2062,7 @@
});
}

function checkOverlap(d, chart) {
function showID(d) {
//click an overlapping ID to see details for that participant
var participantDropdown = chart.multiples.controls.wrap
.style('margin', 0)
.selectAll('.control-group')
.filter(function(d) {
return d.option === 'selected_id';
})
.select('select')
.property('value', d);

//participantDropdown.on("change")() // Can't quite get this to work, so copy/pasting for now ...

var context = chart;
chart.multiples.id = d;
clearSelected.call(context);
context.selected_id = context.multiples.id;
highlightSelected.call(context);
smallMultiples.call(context);

//Trigger participantsSelected event
context.participantsSelected = [context.selected_id];
context.events.participantsSelected.data = context.participantsSelected;
context.wrap.node().dispatchEvent(context.events.participantsSelected);
}

chart.wrap.select('div.overlapNote').remove();

function checkPointOverlap(d, chart) {
// Get the position of the clicked point
var click_x = d3
.select(this)
Expand All @@ -2107,7 +2079,7 @@
var click_id = d.values.raw[0][chart.config.id_col];

// See if any other points overlap
chart.overlap_ids = chart.points
var overlap_ids = chart.points
.filter(function(f) {
var point_id = f.values.raw[0][chart.config.id_col];
var point_x = d3
Expand All @@ -2132,8 +2104,45 @@
return d.values.raw[0][chart.config.id_col];
});

return overlap_ids;
}

function addOverlapNote(d, chart) {
function showID(d) {
//click an overlapping ID to see details for that participant
var participantDropdown = chart.multiples.controls.wrap
.style('margin', 0)
.selectAll('.control-group')
.filter(function(d) {
return d.option === 'selected_id';
})
.select('select')
.property('value', d);

//participantDropdown.on("change")() // Can't quite get this to work, so copy/pasting for now ...

var context = chart;
chart.multiples.id = d;
clearSelected.call(context);
context.selected_id = context.multiples.id;
highlightSelected.call(context);
smallMultiples.call(context);

//Trigger participantsSelected event
context.participantsSelected = [context.selected_id];
context.events.participantsSelected.data = context.participantsSelected;
context.wrap.node().dispatchEvent(context.events.participantsSelected);
}

chart.wrap.select('div.overlapNote').remove();

// check for overlapping points
chart.overlap_ids = checkPointOverlap.call(this, d, chart);

// If there are overlapping points, add a note in the details section.

if (chart.overlap_ids.length) {
var click_id = d.values.raw[0][chart.config.id_col];
var overlap_div = chart.wrap
.insert('div', 'div.multiples')
.attr('class', 'overlapNote')
Expand Down Expand Up @@ -2203,15 +2212,34 @@
}
}

function addOverlapTitle(d, chart) {
// check for overlapping points
var overlap = checkPointOverlap.call(this, d, chart);

// If there are overlapping points, add a note in the details section.

if (overlap.length > 0) {
var titleEl = d3.select(this).select('title');
var currentTitle = titleEl.text();
var hasOverlapNote = currentTitle.search('overlapping'); //minor hack ...
if (hasOverlapNote == -1) {
var newTitle =
currentTitle + '\nNumber of overlapping point(s) = ' + overlap.length;
titleEl.text(newTitle);
}
}
}

function addPointEventListeners() {
var _this = this;

var chart = this;
this.points
.on('mouseover', function(d) {
clearHovered.call(_this);
_this.hovered_id = d.values.raw[0][_this.config.id_col];
if (_this.hovered_id !== _this.selected_id) highlightHovered.call(_this);
addOverlapTitle.call(this, d, chart);
clearHovered.call(chart);
chart.hovered_id = d.values.raw[0][chart.config.id_col];
if (chart.hovered_id !== chart.selected_id) highlightHovered.call(chart);
})
.on('mouseout', function(d) {
clearHovered.call(_this);
Expand All @@ -2229,7 +2257,7 @@
chart.wrap.node().dispatchEvent(chart.events.participantsSelected);

//check for overlapping points
checkOverlap.call(this, d, chart);
addOverlapNote.call(this, d, chart);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import highlightHovered from './functions/highlightHovered';
import clearSelected from './functions/clearSelected';
import highlightSelected from './functions/highlightSelected';
import smallMultiples from './functions/smallMultiples';
import checkOverlap from './functions/checkOverlap';
import addOverlapNote from './functions/addOverlapNote';
import addOverlapTitle from './functions/addOverlapTitle';

export default function addPointEventListeners() {
var chart = this;
this.points
.on('mouseover', d => {
clearHovered.call(this);
this.hovered_id = d.values.raw[0][this.config.id_col];
if (this.hovered_id !== this.selected_id) highlightHovered.call(this);
.on('mouseover', function(d) {
addOverlapTitle.call(this, d, chart);
clearHovered.call(chart);
chart.hovered_id = d.values.raw[0][chart.config.id_col];
if (chart.hovered_id !== chart.selected_id) highlightHovered.call(chart);
})
.on('mouseout', d => {
clearHovered.call(this);
Expand All @@ -28,6 +31,6 @@ export default function addPointEventListeners() {
chart.wrap.node().dispatchEvent(chart.events.participantsSelected);

//check for overlapping points
checkOverlap.call(this, d, chart);
addOverlapNote.call(this, d, chart);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import highlightSelected from './highlightSelected';
import smallMultiples from './smallMultiples';
import clearHovered from './clearHovered';
import highlightHovered from './highlightHovered';
import checkPointOverlap from './checkPointOverlap';

export default function checkOverlap(d, chart) {
export default function addOverlapNote(d, chart) {
function showID(d) {
//click an overlapping ID to see details for that participant
const participantDropdown = chart.multiples.controls.wrap
Expand All @@ -32,47 +33,13 @@ export default function checkOverlap(d, chart) {

chart.wrap.select('div.overlapNote').remove();

// Get the position of the clicked point
const click_x = d3
.select(this)
.select('circle')
.attr('cx');
const click_y = d3
.select(this)
.select('circle')
.attr('cy');
const click_r = d3
.select(this)
.select('circle')
.attr('r');
const click_id = d.values.raw[0][chart.config.id_col];

// See if any other points overlap
chart.overlap_ids = chart.points
.filter(function(f) {
const point_id = f.values.raw[0][chart.config.id_col];
const point_x = d3
.select(this)
.select('circle')
.attr('cx');
const point_y = d3
.select(this)
.select('circle')
.attr('cy');
const distance_x2 = Math.pow(click_x - point_x, 2);
const distance_y2 = Math.pow(click_y - point_y, 2);
const distance = Math.sqrt(distance_x2 + distance_y2);

const max_distance = click_r * 2;
const overlap = distance <= max_distance;
const diff_id = point_id != click_id;
return diff_id & overlap;
})
.data()
.map(d => d.values.raw[0][chart.config.id_col]);
// check for overlapping points
chart.overlap_ids = checkPointOverlap.call(this, d, chart);

// If there are overlapping points, add a note in the details section.

if (chart.overlap_ids.length) {
const click_id = d.values.raw[0][chart.config.id_col];
const overlap_div = chart.wrap
.insert('div', 'div.multiples')
.attr('class', 'overlapNote')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import checkPointOverlap from './checkPointOverlap';

export default function addOverlapTitle(d, chart) {
// check for overlapping points
var overlap = checkPointOverlap.call(this, d, chart);

// If there are overlapping points, add a note in the details section.

if (overlap.length > 0) {
var titleEl = d3.select(this).select('title');
var currentTitle = titleEl.text();
var hasOverlapNote = currentTitle.search('overlapping'); //minor hack ...
if (hasOverlapNote == -1) {
var newTitle = currentTitle + '\nNumber of overlapping point(s) = ' + overlap.length;
titleEl.text(newTitle);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export default function checkPointOverlap(d, chart) {
// Get the position of the clicked point
const click_x = d3
.select(this)
.select('circle')
.attr('cx');
const click_y = d3
.select(this)
.select('circle')
.attr('cy');
const click_r = d3
.select(this)
.select('circle')
.attr('r');
const click_id = d.values.raw[0][chart.config.id_col];

// See if any other points overlap
var overlap_ids = chart.points
.filter(function(f) {
const point_id = f.values.raw[0][chart.config.id_col];
const point_x = d3
.select(this)
.select('circle')
.attr('cx');
const point_y = d3
.select(this)
.select('circle')
.attr('cy');
const distance_x2 = Math.pow(click_x - point_x, 2);
const distance_y2 = Math.pow(click_y - point_y, 2);
const distance = Math.sqrt(distance_x2 + distance_y2);

const max_distance = click_r * 2;
const overlap = distance <= max_distance;
const diff_id = point_id != click_id;
return diff_id & overlap;
})
.data()
.map(d => d.values.raw[0][chart.config.id_col]);

return overlap_ids;
}

0 comments on commit 3b2e378

Please sign in to comment.