Skip to content

Commit f7f077b

Browse files
committed
Filtering features for Data page
1 parent 9e45fa9 commit f7f077b

8 files changed

Lines changed: 605 additions & 39 deletions

File tree

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
<script>
2+
import _ from "lodash";
3+
4+
import NumericChart from "@/components/NumericChart";
5+
import additionalFilterProperties from "./additionalFilterProperties.js";
6+
7+
export default {
8+
name: "AddFilter",
9+
components: {
10+
NumericChart
11+
},
12+
inject: ["girderRest"],
13+
props: {
14+
filter: {
15+
type: Object,
16+
required: false
17+
},
18+
visible: {
19+
type: Boolean,
20+
default: true
21+
}
22+
},
23+
data: () => ({
24+
selectedField: null,
25+
valueRange: [],
26+
includeFilter: true
27+
}),
28+
computed: {
29+
fields: () => [{ value: null, text: "" }, ...additionalFilterProperties],
30+
cleanFilter() {
31+
var filter = { ...this.filter };
32+
delete filter[this.selectedField];
33+
return filter;
34+
},
35+
filter_() {
36+
var filter = {};
37+
if (
38+
this.valueRange[0] !== this.fieldMeta.min ||
39+
this.valueRange[1] !== this.fieldMeta.max
40+
) {
41+
filter[this.selectedField] = {
42+
$gt: this.valueRange[0],
43+
$lt: this.valueRange[1]
44+
};
45+
}
46+
if (this.includeFilter) {
47+
filter = { ...this.cleanFilter, ...filter };
48+
}
49+
return filter;
50+
}
51+
},
52+
asyncComputed: {
53+
async fieldMeta() {
54+
if (!this.selectedField) {
55+
return null;
56+
}
57+
var { data: result } = await this.girderRest.get("meta/field_meta", {
58+
params: {
59+
field: this.selectedField
60+
}
61+
});
62+
return result;
63+
},
64+
async records() {
65+
if (!this.selectedField || !this.fieldMeta) {
66+
return null;
67+
}
68+
var { data: result } = await this.girderRest.get("record/filtered", {
69+
params: {
70+
fields: JSON.stringify([this.selectedField]),
71+
filter: this.filter_
72+
}
73+
});
74+
return result.data.map(data => {
75+
var properties = this.selectedField.split(".");
76+
var value = data;
77+
for (let property of properties) {
78+
value = value[property];
79+
}
80+
return {
81+
_id: data._id,
82+
value: value ? value : 0
83+
};
84+
});
85+
}
86+
},
87+
watch: {
88+
fieldMeta(fieldMeta) {
89+
if (!fieldMeta) {
90+
return;
91+
}
92+
this.valueRange = [fieldMeta.min, fieldMeta.max];
93+
},
94+
visible(value) {
95+
if (!value) {
96+
this.selectedField = null;
97+
this.valueRange = [];
98+
this.includeFilter = true;
99+
}
100+
}
101+
},
102+
methods: {
103+
updateValueRange(value) {
104+
this.valueRange = value;
105+
}
106+
}
107+
};
108+
</script>
109+
110+
<template>
111+
<v-card>
112+
<v-card-title>
113+
Add filter
114+
</v-card-title>
115+
<v-card-text>
116+
<v-row>
117+
<v-col cols="4">
118+
<v-select
119+
:items="fields"
120+
label="Field"
121+
v-model="selectedField"
122+
hide-details
123+
></v-select>
124+
</v-col>
125+
</v-row>
126+
<transition name="fade">
127+
<div v-if="records" class="transition-container">
128+
<v-row no-gutters>
129+
<v-col class="flex-grow-0" style="min-width:60px;">
130+
<v-range-slider
131+
class="two-line mt-2"
132+
vertical
133+
:value="valueRange"
134+
@change="updateValueRange"
135+
:max="fieldMeta.max"
136+
:min="fieldMeta.min"
137+
hide-details
138+
height="360px"
139+
/>
140+
</v-col>
141+
<v-col>
142+
<NumericChart
143+
style="height:400px"
144+
:records="records"
145+
:max="fieldMeta.max"
146+
:min="fieldMeta.min"
147+
/>
148+
</v-col>
149+
</v-row>
150+
<v-checkbox
151+
dense
152+
hide-details
153+
v-model="includeFilter"
154+
label="Include current filters"
155+
></v-checkbox>
156+
</div>
157+
</transition>
158+
</v-card-text>
159+
<v-card-actions>
160+
<v-spacer />
161+
<v-btn
162+
text
163+
color="primary"
164+
:disabled="
165+
!selectedField ||
166+
!fieldMeta ||
167+
(valueRange[0] === fieldMeta.min && valueRange[1] === fieldMeta.max)
168+
"
169+
@click="$emit('add', { [selectedField]: filter_[selectedField] })"
170+
>Add</v-btn
171+
>
172+
</v-card-actions>
173+
</v-card>
174+
</template>
175+
176+
<style lang="scss" scoped>
177+
.transition-container {
178+
height: 440px;
179+
}
180+
</style>
181+
182+
<style lang="scss">
183+
.fade-enter-active,
184+
.fade-leave-active {
185+
transition: all 0.3s ease-in-out;
186+
overflow: hidden;
187+
}
188+
.fade-enter,
189+
.fade-leave-to {
190+
height: 0px !important;
191+
opacity: 0;
192+
}
193+
194+
.v-input__slider.two-line {
195+
.v-input__slot {
196+
height: 360px;
197+
.v-slider {
198+
height: 100%;
199+
}
200+
}
201+
}
202+
</style>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<script>
2+
import Sunburst from "@/components/Sunburst";
3+
import NumericChart from "@/components/NumericChart";
4+
import additionalFilterProperties from "@/components/additionalFilterProperties";
5+
6+
export default {
7+
name: "DataInsight",
8+
inject: ["girderRest"],
9+
components: {
10+
Sunburst,
11+
NumericChart
12+
},
13+
props: ["filter"],
14+
data: () => ({ selectedField: "table8" }),
15+
computed: {
16+
properties() {
17+
return [
18+
{ value: "table8", text: "Sunburst" },
19+
...additionalFilterProperties
20+
];
21+
}
22+
},
23+
asyncComputed: {
24+
async records() {
25+
if (!this.selectedField || this.selectedField === "table8") {
26+
return null;
27+
}
28+
var { data: result } = await this.girderRest.get("record/filtered", {
29+
params: {
30+
fields: JSON.stringify([this.selectedField]),
31+
filter: this.filter
32+
}
33+
});
34+
return result.data.map(data => {
35+
var properties = this.selectedField.split(".");
36+
var value = data;
37+
for (let property of properties) {
38+
value = value[property];
39+
}
40+
return {
41+
_id: data._id,
42+
value: value ? value : 0
43+
};
44+
});
45+
}
46+
}
47+
};
48+
</script>
49+
50+
<template>
51+
<div class="data-insight">
52+
<v-select
53+
class="property-select"
54+
:items="properties"
55+
v-model="selectedField"
56+
hide-details
57+
></v-select>
58+
<Sunburst :filter="filter" v-if="selectedField==='table8'" />
59+
<div class="chart-container" v-else>
60+
<NumericChart
61+
v-if="records"
62+
:records="records"
63+
/>
64+
</div>
65+
</div>
66+
</template>
67+
68+
<style lang="scss" scoped>
69+
.data-insight {
70+
height: 100%;
71+
72+
.property-select {
73+
position: absolute;
74+
right: 20px;
75+
width: 200px;
76+
z-index: 1;
77+
}
78+
79+
.chart-container {
80+
height: 100%;
81+
padding: 5px;
82+
padding-top:30px;
83+
}
84+
}
85+
</style>

0 commit comments

Comments
 (0)