Skip to content

Commit

Permalink
Merge pull request #16 from nih-sparc/feature_distribution-graph
Browse files Browse the repository at this point in the history
Feature distribution graph
  • Loading branch information
SamanthaKraft authored Aug 30, 2024
2 parents a8082b1 + 244e4cb commit ca7f116
Show file tree
Hide file tree
Showing 6 changed files with 1,178 additions and 402 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"test": "vitest"
},
"dependencies": {
"@abi-software/flatmapvuer": "^0.6.1-vue3.8",
"@abi-software/flatmapvuer": "^1.4.1",
"@tsconfig/node21": "^21.0.1",
"axios": "^1.6.7",
"chart.js": "^4.4.2",
Expand Down
47 changes: 7 additions & 40 deletions src/components/FlatmapViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<p><b>Current Location: </b>{{ locationLabel }}</p>
</div>

<FlatmapVuer class="tw-px-2 tw-py-2" :disableUI="disableFlatmapUI" entry="UBERON:1759" v-on:resource-selected="FlatmapSelected" v-on:ready="FlatmapReady"/>
<FlatmapVuer class="tw-px-2 tw-py-2" uuid="685d19d1-cd68-5b0b-b721-de635b98de5f" :disableUI="disableFlatmapUI" entry="UBERON:1759" v-on:resource-selected="FlatmapSelected" v-on:ready="FlatmapReady"/>

</div>

Expand All @@ -15,7 +15,7 @@
import {FlatmapVuer, MultiFlatmapVuer} from '@abi-software/flatmapvuer';
import { useOpenerStore } from "../stores/opener";
import { useLocationStore} from "../stores/locationSelect";
FlatmapVuer.props.flatmapAPI.default="https://mapcore-demo.org/devel/flatmap/v4/";
FlatmapVuer.props.flatmapAPI.default="https://mapcore-demo.org/curation/flatmap/";
defineOptions({
inheritAttrs: false
})
Expand All @@ -39,51 +39,18 @@
const locationLabel = ref("None selected");
function FlatmapSelected(data){
if(locationId===data.feature.featureId){return;}
locationId = data.feature.featureId;
locationLabel.value = data.label;
if(!data.feature.location || locationId===data.feature.location){return;}
locationId = data.feature.location;
const locationMinMax = tempMapToMinMax(locationId);
//send to image selector
emitter.emit("FlatmapViewer-anatomicalLocationSelected",locationMinMax)
}
//this function is my temp work around to not having the map return anything useful
function tempMapToMinMax(id){
switch(id) {
case 3:
return {
min: 0.0,
max: 0.1
}
case 6:
return {
min: 0.1,
max: 0.2
}
case 11:
return {
min: 0.2,
max: 0.3
}
case 11:
return {
min: 0.3,
max: 0.4
}
case 14:
return {
min: 0.4,
max: 0.5
}
case 50:
return {
min: 0.5,
max: 0.7
}
default:
return {
min:0.7,
max:0.8
};
return{
min:id-.1,
max:id+.1
}
}
Expand Down
1 change: 1 addition & 0 deletions src/components/SparcDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ let ComponentListOptions = _globalVars.componentList;
let NewComponent = {};
let NextId = DashboardItems.value.length;
const dBItems = debug ? [{ id: "ODBGraph-1", x: 0, y: 0, h: 4, w:3, componentName:"Flatmap Viewer",component:"QDBGraph" }] :
[{ id: "FlatmapViewer-1", x: 0, y: 0, h: 8, w:2, componentName:"Flatmap Viewer",component:"FlatmapViewer" },
{ id: "ImageSelector-2", x: 2, y: 0, h: 8, w:3, componentName:"Image Selector", component:"ImageSelector"},
Expand Down
70 changes: 66 additions & 4 deletions src/devComponents/QDBGraph/GraphModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const VisualizationMap = new Map()
VisualizationMap.set("Scatter",Scatter);
VisualizationMap.set("Bar", Bar);
VisualizationMap.set("Line",Line);
VisualizationMap.set("Distribution", Bar)

class GraphMetric {
constructor(data = {}){
Expand All @@ -11,12 +12,15 @@ class GraphMetric {
this.fill = data.fill || "";
this.borderColor = data.borderColor || "";
this.backgroundColor = data.backgroundColor || "#f87979";
this._x = [];
this._x = []; //array of points
this._y = [];
this._xAspect = "";
this._yAspect = "";
this._xAspect = ""; //name of aspect
this.xLabels = [];
this._yAspect = "";
this._aspectList=[];
this.metric = "";
this.distValue = data.distValue || "";
this.distPercentage = data.distPercentage || false;
}
set _metric(value){
if(value==="random data") this.ranomizeData();
Expand All @@ -38,7 +42,53 @@ class GraphMetric {
pointDataForBar(){
let pointDataArray=this._x.map(p=>p.value);
this.data = pointDataArray;
}
}
organizeDistribution(){
if(!this.distValue || this._x.length ===0){return;}
let [min,max] = this.findMinMax();
const range = max-min;

let groupings = this.distPercentage ? range*(this.distValue*.01) : parseFloat(this.distValue);
if(range>10){groupings = Math.ceil(groupings)} //this needs to be set by user somehow
const groupingCount = range%groupings>0.1?Math.floor(range/groupings)+1:range/groupings;

let newXArray = [];
let labelsArray = [];
let oldARray = this._x;
for(let x=0;x<groupingCount;x++){
let count = 0;
let start = min;
let stop = min+groupings;
if(x===(groupingCount-1)){stop++}

this._x.forEach(point=>{
if(point.value>=start&&point.value<stop){
count++;
}
})
newXArray.push(count);
labelsArray.push(start.toFixed(2) + " - " + (min+groupings).toFixed(2))
min = stop;
}
this.data = newXArray;
this.xLabels = labelsArray;
//check each value and put into range (or just count)
//return
}
findMinMax(){
const xArr = this._x;
let min =xArr[0].value;
let max = xArr[0].value;
for (var i = 0; i < xArr.length; i++) {
if (xArr[i].value > max ) {
max = xArr[i].value;
}
if(xArr[i].value < min){
min = xArr[i].value;
}
}
return [min, max];
}
ranomizeData(){
let tempArr=[];
let tempArr1 = [];
Expand All @@ -65,6 +115,8 @@ class GraphMetric {
clonedMetric._xAspect = this._xAspect;
clonedMetric._yAspect = this._yAspect;
clonedMetric._metric = this._metric;
clonedMetric.distValue = this.distValue;
clonedMetric.distPercentage = this.distPercentage;
return clonedMetric;
}
}
Expand Down Expand Up @@ -115,6 +167,16 @@ export class GraphSettingsObject {
labels: this.setLabels(),
datasets: this.datasets
}
case "Distribution":
let labelArray = [];
this.datasets.forEach((metric)=>{
metric.organizeDistribution();
labelArray = metric.xLabels;
})
return{
labels: labelArray,
datasets: this.datasets
}
default:
return {};
}
Expand Down
85 changes: 62 additions & 23 deletions src/devComponents/QDBGraph/QDBGraphSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
</div>
<slot>
<div v-for="gm in gMList">
<el-row>

<el-row class="tw-space-x-40 tw-m-2 border-division">

<div class="tw-flex">
<div class="tw-p-1">
Expand All @@ -34,35 +35,64 @@
</el-option>
</el-select>
</div>

<div class="tw-flex tw-flex-col">
<label class="tw-font-bold" >{{ gMList.indexOf(gm)+1+": " }} Metric: </label>
<el-row>
<div class="tw-p-1">

<div v-if="selectedVisual=='Scatter' || selectedVisual=='Line'" class="tw-p-1" >
<label class="tw-font-bold" >y-axis:</label>
<el-select v-model="gm._yAspect" placeholder="select y-axis" class=" tw-w-40">
<el-option
v-for="a in gm._aspectList" :key="a" :label="a" :value="a" @click="changeAxis('_y',a,gm)">
</el-option>
</el-select>
</div>
</div>

<el-select v-model="gm._metric" placeholder="select Metric" class=" tw-w-40">
<el-option
v-for="m in metricList" :key="m" :label="m" :value="m" @click="selectMetric(m, gm)">{{ m }}
</el-option>
</el-select>
</div>
</el-row>
<el-row>
<div class="tw-p-1">
<label>x-axis:</label>
<el-select v-model="gm._xAspect" placeholder="select x-axis" class=" tw-w-40">
<el-option
v-for="a in gm._aspectList" :key="a" :label="a" :value="a" @click="changeAxis('_x',a,gm)">
</el-option>
</el-select>
</div>

<div class="tw-flex">
<div v-if="selectedVisual==='Scatter'" class="tw-p-1" >
<label >y-axis:</label>
<el-select v-model="gm._yAspect" placeholder="select y-axis" class=" tw-w-40">
<el-option
v-for="a in gm._aspectList" :key="a" :label="a" :value="a" @click="changeAxis('_y',a,gm)">
</el-option>
</el-select>
</div>
</el-row>

<div class="tw-p-1">
<label class="tw-font-bold">Label: </label>
<el-input v-model="gm.label" placeholder="Legend" class="tw-w-40 tw-h-8"></el-input>
</div>

<div class="demo-color-block tw-p-1">
<el-color-picker v-model="gm.backgroundColor" />
<div v-if="selectedVisual=='Distribution'" class="tw-flex tw-flex-col">
<div>
<label class="tw-font-bold">Distribution:</label>
<el-input type="number" v-model.number="gm.distValue"></el-input>
<el-select v-model="gm.distPercentage">
<el-option :value="false" label="num">num</el-option>
<el-option :value="true" label="%">%</el-option>
</el-select>
</div>
</div>
<div class="tw-p-1">
<el-button v-if="gMList.indexOf(gm)>0" @click="removeMetric(gm)">-</el-button>

<div class="tw-flex tw-flex-col">
<label class="tw-font-bold">Label: </label>
<div class="tw-p-1 demo-color-block">
<el-input v-model="gm.label" placeholder="Legend" class="tw-w-40 tw-h-8"></el-input>
<el-color-picker v-model="gm.backgroundColor" />
</div>
<div class="tw-p-1">
<el-button style="height: 20px;" v-if="gMList.indexOf(gm)>0" @click="removeMetric(gm)">-</el-button>
</div>
</div>
</div>
</el-row>


</el-row>
</div>

<el-button @click="addMetric()">+</el-button>
Expand Down Expand Up @@ -189,7 +219,7 @@ const getAspectList = async(metric, dataset)=>{
console.log(e)
}
}
//change value of x or y axis
function changeAxis(axis, aspect, metric){
const metricIndex = newGraphData.value.datasets.indexOf(metric);
newGraphData.value.datasets[metricIndex][axis] = aspect;
Expand Down Expand Up @@ -237,4 +267,13 @@ const handleClose = () => {
align-items: center;
margin-bottom: 16px;
}
.border-division{
border-bottom: solid gray 1px;
padding:.5rem;
}
.border-division div {
flex: 1 1 0;
min-height: 20px;
}
</style>
Loading

0 comments on commit ca7f116

Please sign in to comment.