Skip to content

Commit

Permalink
Hover pin (#813)
Browse files Browse the repository at this point in the history
* clickable dots register what is clicked

* tooltip can be pinned! now to unpin

* little close link in tooltip

* tooltip can be unpinned

* visibility hide/show for little x close box

* styling the close button

* links appear to be working

* preparing to put links in phewas hover

* almost there

* links working

* links on phenotype page too
  • Loading branch information
moriondo2022 authored Dec 13, 2024
1 parent 9d6598a commit dce3b0a
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 45 deletions.
50 changes: 43 additions & 7 deletions src/components/PigeanPlot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import Vue from "vue";
import * as d3 from "d3";
import DownloadChart from "./DownloadChart.vue";
import plotUtils from "@/utils/plotUtils";
import bioIndexUtils from "@/utils/bioIndexUtils";
import Formatters from "@/utils/formatters";
import { BootstrapVueIcons } from "bootstrap-vue";
Vue.use(BootstrapVueIcons);
export default Vue.component("pigean-plot", {
components: {
},
props: ["pigeanData", "config", "phenotypeMap", "filter"],
props: ["pigeanData", "config", "phenotypeMap", "filter", "genesetSize", "traitGroup"],
data() {
return {
plotId: `pigean-plot-${Math.floor(Math.random() * 10e9)}`,
Expand All @@ -34,6 +37,7 @@ export default Vue.component("pigean-plot", {
xMedian: 0,
tooltip: null,
tooltipElement: null,
tooltipPinned: false,
colorMap: this.groupColors(),
allHoverFields: this.getHoverFields(),
hoverBoxPosition: this.config.hoverBoxPosition || "left",
Expand All @@ -56,10 +60,17 @@ export default Vue.component("pigean-plot", {
data = data.filter(this.filter);
}
return data;
},
linkSuffix(){
return `&genesetSize=${this.$store.state.genesetSize
|| bioIndexUtils.DEFAULT_GENESET_SIZE
}&traitGroup=${this.$store.state.traitGroup
|| bioIndexUtils.DEFAULT_TRAIT_GROUP}`;
}
},
methods: {
drawChart(){
this.tooltipPinned = false;
let margin = {
top: 10,
right: 30,
Expand All @@ -74,7 +85,6 @@ export default Vue.component("pigean-plot", {
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.on("mouseleave", () => this.hideTooltip())
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
Expand Down Expand Up @@ -151,6 +161,16 @@ export default Vue.component("pigean-plot", {
.attr("stroke", this.dotOutlineColor)
.on("mouseover", (g) =>
this.hoverDot(JSON.stringify(g)));
// Click behavior for dots
this.svg.selectAll("circle")
.on("click", d => {
if (!this.tooltipPinned){
let closeButton = this.tooltip.select("a");
closeButton.style("visibility", "visible");
this.tooltipPinned = true;
}
});
},
extremeVal(field, min=true){
let filteredData = this.pigeanData.filter(d =>
Expand All @@ -166,16 +186,22 @@ export default Vue.component("pigean-plot", {
return val;
},
hoverDot(dotString) {
if (this.tooltipPinned){
return;
}
this.unHoverDot();
this.$emit("dotHovered", dotString);
let xcoord = d3.event.layerX;
let ycoord = d3.event.layerY;
// Tooltip content
this.tooltip
.style("opacity", 1)
.html(this.getTooltipContent(dotString));
this.tooltip.selectAll("a")
.on("click", () => {
this.tooltipPinned = false;
this.hideTooltip();
});
let leftOffset = this.tooltipElement.clientWidth;
let hoverLeft = this.dotHoverLeft(dotString);
Expand All @@ -196,11 +222,16 @@ export default Vue.component("pigean-plot", {
: this.hoverBoxPosition === "left";
},
getTooltipContent(dotString){
console.log(dotString);
let dot = JSON.parse(dotString);
let dKey = this.config.dotKey;
let dKeyContent = dot[dKey]; // Get raw content before formatting
dot.phenotype = this.phDesc(dot.phenotype);
let tooltipText = `${
Formatters.tissueFormatter(this.config.dotKey)}: ${
dot[this.config.dotKey]}`;
let linkAddress = `/pigean/${dKey}.html?${dKey}=${dKeyContent}${this.linkSuffix}`;
let tooltipText = '<p class="close-tooltip"><a style="visibility:hidden">';
tooltipText = tooltipText.concat('x</a><p>')
tooltipText=tooltipText.concat(`${
Formatters.tissueFormatter(dKey)}: <a href="${linkAddress}">${dot[dKey]}</a>`);
tooltipText = tooltipText.concat(
`<span>${this.config.xAxisLabel}: ${
dot[this.config.xField]}</span>`);
Expand Down Expand Up @@ -282,4 +313,9 @@ export default Vue.component("pigean-plot", {
.tooltip span {
display: block;
}
p.close-tooltip{
text-align: right;
margin: 0px;
padding: 0px;
}
</style>
2 changes: 2 additions & 0 deletions src/components/PigeanTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ export default Vue.component("pigean-table", {
:plot-name="`PIGEAN_${row.item.phenotype}`"
:phenotypes-data="phewasData[phewasKey(row.item)]"
:phenotype-map="phenotypeMap || $store.state.bioPortal.phenotypeMap"
:linkPhenotypes="true"
:isPigean="true"
:colors="plotColors"
:render-config="phewasRenderConfig"
:utils="utilsBox"
Expand Down
43 changes: 30 additions & 13 deletions src/components/researchPortal/ResearchPheWAS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@
<span :id="canvasId + 'pheWasInfoBoxContent'"></span>

<span v-for="(ptValue, ptKey) in hoverItems" :key="ptKey">
<strong>{{ ptKey }}</strong
><br />
<strong v-if="!linkPhenotypes">{{ ptKey }}</strong>
<strong v-else>
<a :href="phenotypeLink(ptKey)">
{{ phenotypeMap[ptKey].description }}
</a>
</strong>
<br />
<span
v-for="(dValue, dKey) in ptValue.data"
:key="dKey"
Expand Down Expand Up @@ -152,6 +157,7 @@
import Vue from "vue";
import { cloneDeep } from "lodash";
import { BootstrapVueIcons } from "bootstrap-vue";
import bioIndexUtils from "@/utils/bioIndexUtils";
import pheWasPlotVector from "@/components/researchPortal/vectorPlots/ResearchPheWasPlotVector.vue";
Vue.use(BootstrapVueIcons);
Expand All @@ -175,6 +181,8 @@ export default Vue.component("ResearchPhewasPlot", {
"utils",
"plotName",
"top1500",
"linkPhenotypes",
"isPigean"
],
data() {
Expand Down Expand Up @@ -427,12 +435,12 @@ export default Vue.component("ResearchPhewasPlot", {
if (y >= yLoc[0] && y <= yLoc[1]) {
yValue.map((xPos) => {
if (x >= xPos.start && x <= xPos.end) {
this.hoverItems[xPos.name] = xPos;
infoContent +=
"<strong>" +
xPos.name +
"</strong><br />";
if (this.linkPhenotypes){
this.hoverItems[xPos.id] = xPos;
} else {
this.hoverItems[xPos.name] = xPos;
}
infoContent +=`<strong>${xPos.name}</strong><br />`;
this.renderConfig["hover content"].map(
(h) => {
infoContent +=
Expand Down Expand Up @@ -755,13 +763,11 @@ export default Vue.component("ResearchPhewasPlot", {
canvasHeight -
plotMargin.bottom -
yFromMinY * yStep;
let rawPhenotype = p[this.renderConfig["render by"]];
let pName =
this.phenotypeMapConfig == null
? p[this.renderConfig["render by"]]
: this.phenotypeMap[
p[this.renderConfig["render by"]]
]["description"];
? rawPhenotype
: this.phenotypeMap[rawPhenotype]["description"];
let passesThreshold = this.greaterThan
? p.rawPValue >=
Number(this.renderConfig["thresholds"][0])
Expand Down Expand Up @@ -1081,6 +1087,17 @@ export default Vue.component("ResearchPhewasPlot", {
action: "remove",
});
},
phenotypeLink(rawPhenotype){
let destination = `/phenotype.html?phenotype=${rawPhenotype}`;
if (this.isPigean){
let suffix = `&genesetSize=${this.$store.state.genesetSize
|| bioIndexUtils.DEFAULT_GENESET_SIZE
}&traitGroup=${this.$store.state.traitGroup
|| bioIndexUtils.DEFAULT_TRAIT_GROUP}`;
destination = `/pigean${destination}${suffix}`;
}
return destination;
}
},
});
</script>
Expand Down
11 changes: 2 additions & 9 deletions src/views/PIGEAN/Gene/Template.vue
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@
:phenotype-map="
$parent.pigeanMap
"
:linkPhenotypes="true"
:isPigean="true"
:colors="$parent.plotColors"
:render-config="$parent.renderConfig"
:utils="$parent.utilsBox"
Expand All @@ -160,17 +162,8 @@
$parent.pigeanMap
"
:filter="filter"
@dotHovered="(dot) => $parent.showLink(dot)"
>
</pigean-plot>
<div id="pigean-hover-link">
<p v-if="!!$parent.phenotypeLinkAddress">
View phenotype:
<a :href="$parent.phenotypeLinkAddress"
v-html="$parent.phenotypeLinkText">
</a>
</p>
</div>
</div>
</div>
<div class="card-body pigean-table">
Expand Down
16 changes: 0 additions & 16 deletions src/views/PIGEAN/Gene/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ new Vue({
data() {
return {
pigeanPhenotypeMap: {},
hoverPhenotype: "",
filterFields: [
{ key: "combined", label: "Combined genetic support" },
{ key: "huge_score", label: "Direct support w/o gene sets" },
Expand Down Expand Up @@ -170,17 +169,6 @@ new Vue({
phewasAllData(){
return this.$store.state.phewasData;
},
phenotypeLinkAddress(){
if (!this.hoverPhenotype){
return "";
}
return `/pigean/phenotype.html?phenotype=${this.hoverPhenotype
}&genesetSize=${this.$store.state.genesetSize}&traitGroup=${
this.$store.state.traitGroup}`;
},
phenotypeLinkText(){
return this.pigeanMap[this.hoverPhenotype]?.description || this.hoverPhenotype;
}
},
watch: {
diseaseGroup(group) {
Expand All @@ -207,10 +195,6 @@ new Vue({
}&start=${r.start - expanded}&end=${r.end + expanded}`;
}
},
showLink(dot){
let dotObject = JSON.parse(dot);
this.hoverPhenotype = dotObject.phenotype;
}
},

render(createElement, context) {
Expand Down
2 changes: 2 additions & 0 deletions src/views/PIGEAN/GeneSet/Template.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@
$parent.phewasAdjustedData
"
:phenotype-map="$parent.pigeanMap"
:linkPhenotypes="true"
:isPigean="true"
:colors="$parent.plotColors"
:render-config="$parent.renderConfig"
:utils="$parent.utilsBox"
Expand Down

0 comments on commit dce3b0a

Please sign in to comment.