Skip to content

Commit 6408cbf

Browse files
authored
Embedding visualization connect (#356)
* Make the frontend to fetch the data from the flask server. * Provide loading animation. * Fixed format style Fix the issue where the display label not working. * Provide a 2D 3D switcher. Display the chart in 3D. * Include PCA method to do dimension reduction * Fix the style. * Fix typo Use === to compare type as well.
1 parent 5a07774 commit 6408cbf

File tree

7 files changed

+241
-64
lines changed

7 files changed

+241
-64
lines changed

frontend/mock/data/plugin/embeddings/embeddings.js

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,86 @@
66
* @param {Object} postParam post params
77
* @return {Object}
88
*/
9-
module.exports = function (path, queryParam, postParam) {
10-
return {
11-
// moock delay
12-
_timeout: 0,
13-
// mock http status
14-
_status: 200,
15-
// mock response data
16-
_data: {
17-
status: 0,
18-
msg: 'SUCCESS',
19-
data: {
20-
"embedding": [
21-
[10.0, 8.04, "yellow"],
22-
[8.0, 6.95, "blue"],
23-
[13.0, 7.58, "red"],
24-
[9.0, 8.81, "king"],
25-
[11.0, 8.33, "queen"],
26-
[14.0, 9.96, "man"],
27-
[6.0, 7.24, "women"],
28-
[4.0, 4.26, "kid"],
29-
[12.0, 10.84, "adult"],
30-
[7.0, 4.82, "light"],
31-
[5.0, 5.68, "dark"]
32-
]
9+
module.exports = function(path, queryParam, postParam) {
10+
if (queryParam.dimension === '3') {
11+
return {
12+
// moock delay
13+
_timeout: 0,
14+
// mock http status
15+
_status: 200,
16+
// mock response data
17+
_data: {
18+
status: 0,
19+
msg: 'SUCCESS',
20+
data: {
21+
"embedding": [
22+
[10.0, 8.04, 3],
23+
[8.0, 6.95, 4],
24+
[13.0, 7.58, 1],
25+
[9.0, 8.81, 3],
26+
[11.0, 8.33, 5],
27+
[14.0, 9.96, 6],
28+
[6.0, 7.24, 1],
29+
[4.0, 4.26, 2],
30+
[12.0, 10.84, 6],
31+
[7.0, 4.8, 3],
32+
[5.0, 5.68, 3]
33+
],
34+
"labels": [
35+
"yellow",
36+
"blue",
37+
"red",
38+
"king",
39+
"queen",
40+
"man",
41+
"women",
42+
"kid",
43+
"adult",
44+
"light",
45+
"dark"
46+
]
47+
}
3348
}
34-
}
35-
};
49+
};
50+
} else {
51+
return {
52+
// moock delay
53+
_timeout: 0,
54+
// mock http status
55+
_status: 200,
56+
// mock response data
57+
_data: {
58+
status: 0,
59+
msg: 'SUCCESS',
60+
data: {
61+
"embedding": [
62+
[10.0, 8.04],
63+
[8.0, 6.95],
64+
[13.0, 7.58],
65+
[9.0, 8.81],
66+
[11.0, 8.33],
67+
[14.0, 9.96],
68+
[6.0, 7.24],
69+
[4.0, 4.26],
70+
[12.0, 10.84],
71+
[7.0, 4.8],
72+
[5.0, 5.68]
73+
],
74+
"labels": [
75+
"yellow",
76+
"blue",
77+
"red",
78+
"king",
79+
"queen",
80+
"man",
81+
"women",
82+
"kid",
83+
"adult",
84+
"light",
85+
"dark"
86+
]
87+
}
88+
}
89+
};
90+
}
3691
};

frontend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"d3-format": "^1.2.1",
2121
"dagre": "^0.8.2",
2222
"dagre-d3": "^0.6.1",
23-
"echarts": "^3.8.5",
23+
"echarts": "^4.0.0",
24+
"echarts-gl": "^1.1.0",
2425
"file-saver": "^1.3.3",
2526
"graphlib": "^1.0.5",
2627
"htmlcs": "^0.4.1",

frontend/src/high-dimensional/HighDimensional.vue

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
:config="config"
66
:displayWordLabel="config.displayWordLabel"
77
:searchText="config.searchText"
8+
:dimension="config.dimension"
89
:embedding_data="embedding_data"
910
></ui-chart>
1011
</div>
@@ -35,20 +36,45 @@ export default {
3536
config: {
3637
searchText: '',
3738
displayWordLabel: true,
39+
dimension: "2",
40+
reduction: "tsne",
3841
running: true
3942
},
4043
embedding_data: []
4144
}
4245
},
4346
created() {
44-
getHighDimensionalDatasets().then(({errno, data}) => {
45-
this.embedding_data = data.embedding;
46-
});
47+
this.fetchDatasets()
48+
},
49+
watch: {
50+
'config.dimension': function(val) {
51+
this.fetchDatasets()
52+
},
53+
'config.reduction': function(val) {
54+
this.fetchDatasets()
55+
}
4756
},
4857
mounted() {
4958
autoAdjustHeight();
5059
},
5160
methods: {
61+
fetchDatasets() {
62+
// Fetch the data from the server. Passing dimension and reduction method
63+
let params = {
64+
dimension: this.config.dimension,
65+
reduction: this.config.reduction
66+
};
67+
getHighDimensionalDatasets(params).then(({errno, data}) => {
68+
var vector_data = data.embedding;
69+
var labels = data.labels;
70+
71+
for ( var i = 0; i < vector_data.length; i ++) {
72+
vector_data[i].push(labels[i])
73+
}
74+
75+
this.embedding_data = vector_data
76+
});
77+
},
5278
}
5379
};
5480

frontend/src/high-dimensional/ui/Chart.vue

Lines changed: 85 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
<script>
99
import echarts from 'echarts';
10+
import 'echarts-gl';
1011
1112
export default {
12-
props: ['config', 'displayWordLabel', 'searchText', 'embedding_data'],
13+
props: ['config', 'displayWordLabel', 'searchText', 'embedding_data', 'dimension'],
1314
data() {
1415
return {
1516
width: 900,
@@ -18,20 +19,21 @@ export default {
1819
},
1920
computed: {
2021
computedStyle() {
21-
return 'height:' + this.height + 'px;'
22-
+ 'width:' + this.width + 'px;';
22+
return 'height:' + this.height + 'px;' +
23+
'width:' + this.width + 'px;';
2324
}
2425
},
25-
created() {
26-
27-
},
26+
created() {},
2827
mounted() {
2928
this.createChart();
30-
this.setChartsOptions();
29+
this.myChart.showLoading()
30+
31+
this.set2DChartOptions();
3132
this.setDisplayWordLabel();
3233
},
3334
watch: {
3435
embedding_data: function(val) {
36+
this.myChart.hideLoading();
3537
this.myChart.setOption({
3638
series: [{
3739
// Grab the 'matched' series data
@@ -43,13 +45,25 @@ export default {
4345
displayWordLabel: function(val) {
4446
this.setDisplayWordLabel()
4547
},
48+
dimension: function(val) {
49+
this.myChart.clear()
50+
this.myChart.showLoading()
51+
if (val === "2") {
52+
this.set2DChartOptions();
53+
this.setDisplayWordLabel();
54+
} else {
55+
this.set3DChartOptions();
56+
this.setDisplayWordLabel();
57+
}
58+
},
4659
searchText: function(val) {
60+
// Filter the data that has the hasPrefix
4761
var matched_words = []
4862
if (val != '') {
4963
val = val.toLowerCase()
5064
5165
function hasPrefix(value) {
52-
var word = value[2]
66+
var word = value[value.length - 1]
5367
return (typeof word == "string" && word.toLowerCase().startsWith(val))
5468
}
5569
@@ -72,13 +86,12 @@ export default {
7286
let el = this.$refs.chartBox;
7387
this.myChart = echarts.init(el);
7488
},
75-
setChartsOptions(){
89+
set2DChartOptions() {
7690
var typeD = "normal";
7791
var option = {
7892
xAxis: {},
7993
yAxis: {},
80-
series: [
81-
{
94+
series: [{
8295
name: "all",
8396
symbolSize: 10,
8497
data: this.embedding_data,
@@ -87,45 +100,88 @@ export default {
87100
{
88101
name: "matched",
89102
animation: false,
90-
symbolSize:10,
103+
symbolSize: 10,
91104
data: [],
92105
itemStyle: {
93106
normal: {
94107
opacity: 1
95108
}
96109
},
97110
label: {
111+
normal: {
112+
show: true,
113+
formatter: function(param) {
114+
return param.data[param.data.length - 1];
115+
},
116+
position: 'top'
117+
}
118+
},
119+
type: 'scatter'
120+
}
121+
]
122+
};
123+
this.myChart.setOption(option);
124+
},
125+
set3DChartOptions() {
126+
var symbolSize = 2.5;
127+
var option3d = {
128+
grid3D: {},
129+
xAxis3D: {
130+
type: 'category'
131+
},
132+
yAxis3D: {},
133+
xAxis3D: {},
134+
zAxis3D: {},
135+
dataset: {
136+
source: this.embedding_data
137+
},
138+
series: [
139+
{
140+
name: "all",
141+
type: 'scatter3D',
142+
symbolSize: symbolSize,
143+
data: []
144+
},
145+
{
146+
name: "matched",
147+
animation: false,
148+
symbolSize: symbolSize,
149+
data: [],
150+
label: {
98151
normal: {
99152
show: true,
100-
formatter: function (param) {
101-
return param.data[2];
153+
formatter: function(param) {
154+
return param.data[param.data.length - 1];
102155
},
103156
position: 'top'
104157
}
105158
},
106-
type: 'scatter'
107-
}
108-
]
109-
};
110-
this.myChart.setOption(option);
159+
type: 'scatter3D'
160+
}
161+
]
162+
}
163+
this.myChart.setOption(option3d);
111164
},
112165
setDisplayWordLabel() {
113-
this.myChart.setOption({
166+
this.myChart.setOption({
167+
series: [{
168+
// Grab the 'all' series data
169+
name: 'all',
114170
label: {
115171
normal: {
116172
show: this.displayWordLabel,
117-
formatter: function (param) {
118-
return param.data[2];
119-
},
120-
position: 'top'
173+
formatter: function(param) {
174+
return param.data[param.data.length - 1];
121175
},
122-
emphasis: {
123-
show: true,
124-
}
176+
position: 'top'
177+
},
178+
emphasis: {
179+
show: true,
125180
}
126-
})
181+
}
182+
}]
183+
});
127184
},
128-
129185
}
130186
};
131187
@@ -136,7 +192,4 @@ export default {
136192
float left
137193
padding 10px
138194
position relative
139-
140-
141-
142195
</style>

0 commit comments

Comments
 (0)