Skip to content

Commit dfb2759

Browse files
committed
Polish Landing page functionality
1 parent 95c87f9 commit dfb2759

10 files changed

Lines changed: 324 additions & 103 deletions

File tree

client/src/components/BiomeTreemap.vue

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,21 @@ export default {
7171
.paddingInner(2);
7272
var nodes = layout(this.treemapData);
7373
74+
var leaves = nodes.leaves();
75+
if (leaves.length === 1 && leaves[0].data.name === "biome") {
76+
d3.select(this.$el)
77+
.selectAll(".leaf")
78+
.remove();
79+
return;
80+
}
81+
7482
var svg = d3.select(this.$el);
7583
svg
7684
.selectAll(".leaf")
77-
.data(nodes.leaves(), d => d.data.name)
85+
.data(leaves, d => d.data.name)
7886
.join(
7987
enter => {
80-
var leaf = enter
88+
var leaves = enter
8189
.append("div")
8290
.attr("class", "leaf")
8391
.classed(
@@ -112,26 +120,27 @@ export default {
112120
}
113121
});
114122
115-
leaf
123+
leaves
116124
.append("div")
117125
.attr("class", "leaf-title")
118126
.text(d => {
119127
if (d.y1 - d.y0 < 14) {
120128
return;
121129
}
122-
if (d.x1 - d.x0 < d.data.name.length * 10) {
130+
var name = d.data.name.replace(" biome", "");
131+
if (d.x1 - d.x0 < name.length * 10) {
123132
return;
124133
}
125-
return d.data.name;
134+
return name;
126135
});
127136
128-
leaf
137+
leaves
129138
.append("div")
130139
.attr("class", "leaf-value")
131140
.text(d => d.data.value);
132141
},
133142
update => {
134-
var leaf = update
143+
var leaves = update
135144
.classed(
136145
"selected",
137146
d => this.selections.indexOf(d.data.name) !== -1
@@ -144,7 +153,7 @@ export default {
144153
.style("height", d => `${d.y1 - d.y0}px`)
145154
.style("background-color", d => mapColor("biome", d.data.name));
146155
147-
leaf.select(".leaf-title").text(d => {
156+
leaves.select(".leaf-title").text(d => {
148157
if (d.y1 - d.y0 < 14) {
149158
return;
150159
}
@@ -153,7 +162,7 @@ export default {
153162
}
154163
return d.data.name;
155164
});
156-
leaf.select(".leaf-value").text(d => d.data.value);
165+
leaves.select(".leaf-value").text(d => d.data.value);
157166
},
158167
remove => {
159168
remove
@@ -188,14 +197,16 @@ export default {
188197
position: absolute;
189198
overflow: hidden;
190199
transition: transform 0.4s;
200+
border: solid 2px transparent;
191201
192202
&:hover {
193203
transition: transform 0.2s;
194-
transform: scale(0.98);
204+
transform: scale(0.97) !important;
195205
}
196206
197207
&.selected {
198208
border: solid 2px black;
209+
transform: scale(0.99);
199210
}
200211
201212
.leaf-title {

client/src/components/FeatureVsMaterialChart.vue

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default {
3434
{ params }
3535
);
3636
records.sort((a, b) => (a.material > b.material ? 1 : -1));
37-
return records;
37+
return [...records];
3838
}
3939
},
4040
watch: {
@@ -55,7 +55,7 @@ export default {
5555
},
5656
methods: {
5757
initialize() {
58-
var margin = { top: 70, right: 80, bottom: 70, left: 40 };
58+
var margin = { top: 70, right: 40, bottom: 70, left: 40 };
5959
var width = this.$el.clientWidth - margin.left - margin.right;
6060
this.width = width;
6161
var height = this.$el.clientHeight - margin.top - margin.bottom;
@@ -179,22 +179,34 @@ export default {
179179
.attr("text-anchor", "end")
180180
.text("Count");
181181
182-
svg
182+
var barContainer = svg
183183
.selectAll(".bar")
184184
.data(records, record => record.feature + record.material)
185185
.enter()
186+
.append("g")
187+
.attr("class", "bar-container")
188+
.attr(
189+
"transform",
190+
record => `translate(${x(records.indexOf(record))},0)`
191+
);
192+
193+
barContainer
194+
.append("line")
195+
.attr("class", "indicator")
196+
.attr("x1", x.bandwidth() / 2)
197+
.attr("x2", x.bandwidth() / 2)
198+
.attr("y2", height);
199+
200+
var bar = barContainer
186201
.append("rect")
187202
.attr("class", "bar")
188-
.attr("x", record => {
189-
return x(records.indexOf(record));
190-
})
191-
.attr("y", record => {
192-
return y(record.count);
193-
})
194203
.attr("width", x.bandwidth())
195204
.attr("height", record => {
196205
return height - y(record.count);
197206
})
207+
.attr("y", record => {
208+
return y(record.count);
209+
})
198210
.attr("fill", d =>
199211
d3.interpolateRgb(
200212
mapColor("feature", d.feature),
@@ -210,13 +222,10 @@ export default {
210222
.style(
211223
"transform-origin",
212224
record =>
213-
`${x(records.indexOf(record)) + x.bandwidth() / 2}px ${y(
214-
record.count
215-
) +
225+
`${x.bandwidth() / 2}px ${y(record.count) +
216226
(height - y(record.count)) / 2}px`
217227
)
218228
.on("click", record => {
219-
// d3.event.preventDefault();
220229
var index = this.featureSelections.indexOf(record.feature);
221230
var index2 = this.materialSelections.indexOf(record.material);
222231
if (index !== -1 && index2 !== -1) {
@@ -241,10 +250,9 @@ export default {
241250
record.material
242251
]);
243252
}
244-
// return false;
245-
})
246-
.append("title")
247-
.text(d => `${d.material} / ${d.feature}\n${d.count}`);
253+
});
254+
255+
bar.append("title").text(d => `${d.material} / ${d.feature}\n${d.count}`);
248256
},
249257
out() {
250258
console.log(arguments);
@@ -265,12 +273,28 @@ export default {
265273

266274
<style lang="scss">
267275
.feature-material-chart {
268-
.bar {
269-
transition: transform 0.2s;
270-
stroke-width: 2px;
276+
.bar-container {
277+
.indicator {
278+
visibility: hidden;
279+
fill: none;
280+
stroke: grey;
281+
stroke-dasharray: 3 5;
282+
stroke-width: 1;
283+
}
271284
272285
&:hover {
273-
transform: scaleX(0.93) scaleY(0.98);
286+
.indicator {
287+
visibility: visible;
288+
}
289+
}
290+
291+
.bar {
292+
transition: transform 0.2s;
293+
stroke-width: 2px;
294+
295+
&:hover {
296+
transform: scaleX(0.93) scaleY(0.98);
297+
}
274298
}
275299
}
276300

client/src/components/SamplesLocation.vue

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
<script>
2+
import * as d3 from "d3";
3+
4+
import { mapColor } from "@/util/colors";
5+
26
export default {
37
name: "SamplesLocation",
48
inject: ["girderRest"],
59
props: {
610
filter: {
711
type: Object,
812
required: false
13+
},
14+
selectedRegion: {
15+
type: Object,
16+
required: false
917
}
1018
},
19+
data: () => ({
20+
annotationGeojson: null,
21+
editing: false
22+
}),
1123
computed: {
1224
sitesFeature() {
1325
if (!this.locations) {
@@ -19,17 +31,23 @@ export default {
1931
return {
2032
type: "FeatureCollection",
2133
features: this.locations.map(location => {
34+
var colors = [
35+
...location.features.map(feature => mapColor("feature", feature)),
36+
...location.materials.map(material =>
37+
mapColor("material", material)
38+
),
39+
...location.biomes.map(biome => mapColor("biome", biome))
40+
];
41+
// console.log();
2242
return {
2343
type: "Feature",
2444
geometry: {
2545
type: "Point",
26-
coordinates: [
27-
parseFloat(location.longitude),
28-
parseFloat(location.latitude)
29-
]
46+
coordinates: [location.longitude, location.latitude]
3047
},
3148
properties: {
32-
radius: 3 + (location.count / (max - min)) * 30
49+
radius: 3 + (location.count / (max - min)) * 30,
50+
fillColor: this.averageColor(colors).hex()
3351
}
3452
};
3553
})
@@ -50,14 +68,34 @@ export default {
5068
sitesFeature() {
5169
this.$refs.map.toGeoJSON(this.sitesFeature, {
5270
animate: 1000,
53-
bufferPercentage: 4
71+
bufferDistance: 20
5472
});
73+
},
74+
annotationGeojson(value) {
75+
if (value) {
76+
this.$emit("update:selectedRegion", value);
77+
this.geojson = value;
78+
}
79+
this.annotationGeojson = null;
5580
}
5681
},
5782
async mounted() {
5883
setTimeout(() => {
5984
window.dispatchEvent(new Event("resize"));
6085
}, 0);
86+
},
87+
methods: {
88+
averageColor(colors) {
89+
var colorList = colors.map(color => d3.color(color));
90+
return d3.rgb(
91+
colorList.map(color => color.r).reduce((a, b) => a + b, 0) /
92+
colorList.length,
93+
colorList.map(color => color.g).reduce((a, b) => a + b, 0) /
94+
colorList.length,
95+
colorList.map(color => color.b).reduce((a, b) => a + b, 0) /
96+
colorList.length
97+
);
98+
}
6199
}
62100
};
63101
</script>
@@ -69,12 +107,53 @@ export default {
69107
attribution="© OpenStreetMap contributors, © CARTO"
70108
:zIndex="0"
71109
/>
72-
<GeojsGeojsonLayer :zIndex="1" :geojson="sitesFeature" />
110+
<GeojsGeojsonLayer
111+
:zIndex="1"
112+
:geojson="sitesFeature"
113+
:featureStyle="{
114+
point: {stroke: false }
115+
}" />
116+
<GeojsGeojsonLayer
117+
:zIndex="2"
118+
:geojson="selectedRegion"
119+
:featureStyle="{
120+
polygon: { fill: false, strokeColor: 'black', strokeWidth: 2 }
121+
}"
122+
/>
123+
<GeojsSimpleAnnotationLayer
124+
:zIndex="3"
125+
:geojson.sync="annotationGeojson"
126+
:editing.sync="editing"
127+
/>
128+
<div class="draw">
129+
<v-btn
130+
fab
131+
small
132+
v-if="!selectedRegion"
133+
@mousedown.stop
134+
@click="editing = editing ? null : 'rectangle'"
135+
>
136+
<v-icon dark>{{
137+
editing ? "mdi-close" : "mdi-shape-rectangle-plus"
138+
}}</v-icon>
139+
</v-btn>
140+
<v-btn
141+
fab
142+
small
143+
v-if="selectedRegion"
144+
@mousedown.stop
145+
@click="$emit('update:selectedRegion', null)"
146+
><v-icon dark>mdi-delete</v-icon>
147+
</v-btn>
148+
</div>
73149
</GeojsMapViewport>
74150
</template>
75151

76152
<style lang="scss" scoped>
77-
.v-card {
78-
height: 100%;
153+
.draw {
154+
position: absolute;
155+
z-index: 2;
156+
left: 15px;
157+
top: 15px;
79158
}
80159
</style>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<template functional>
2+
<div class="widget-container">
3+
<div class="grey darken-2 white--text body-2 pl-2"><slot name="title"></slot></div>
4+
<div class="widget flex-grow-1">
5+
<slot />
6+
</div>
7+
</div>
8+
</template>
9+
10+
<style lang="scss" scoped>
11+
.widget-container {
12+
height: 100%;
13+
display: flex;
14+
flex-direction: column;
15+
}
16+
</style>

0 commit comments

Comments
 (0)