Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:Duke-MatSci/materialsmine into #…
Browse files Browse the repository at this point in the history
…156_Update_ICO
  • Loading branch information
tholulomo committed Apr 5, 2022
2 parents e62b71d + c8d5daa commit 345e310
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 13 deletions.
3 changes: 2 additions & 1 deletion app/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ module.exports = {
'<rootDir>/node_modules/jest-serializer-vue'
],
moduleNameMapper: {
d3: '<rootDir>/node_modules/d3/dist/d3.min.js'
d3: '<rootDir>/node_modules/d3/dist/d3.min.js',
'style-loader!(.*)': '<rootDir>/node_modules/style-loader'
},
setupFilesAfterEnv: ['<rootDir>/tests/jest/script/test-setup.js']
}
1 change: 1 addition & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"sinon": "^12.0.1",
"style-loader": "^2.0.0",
"vue-template-compiler": "^2.6.11"
},
"gitHooks": {
Expand Down
14 changes: 14 additions & 0 deletions app/src/assets/css/modules/_vega.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,17 @@
left: 0rem !important;
}
}

.datavoyager {
margin: 0rem 2.5rem;
&-title {
font-weight: 500;
color: $primary-grey
}
#voyager-embed {
background: $primary-white;
height: 100%;
width: calc(100% - 2rem);
margin: 2rem 1rem;
}
}
56 changes: 56 additions & 0 deletions app/src/components/explorer/DataVoyager.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<div>
<div :id="containerId" :ref="containerId"></div>
</div>
</template>

<script>
import { CreateVoyager } from 'datavoyager'
const voyagerConf = {
showDataSourceSelector: false,
hideHeader: true,
hideFooter: true
}
export default {
name: 'DataVoyager',
data () {
return {
containerId: 'voyager-embed'
}
},
props: {
data: {
type: Object,
default: () => null
},
spec: {
type: Object,
default: () => null
}
},
methods: {
updateSpec () {
this.$emit('update:spec', this.voyagerInstance.getSpec())
},
createVoyager () {
const container = this.$refs[this.containerId]
this.voyagerInstance = CreateVoyager(container, voyagerConf, undefined)
this.voyagerInstance.onStateChange(() => this.updateSpec())
this.voyagerInstance.updateData(this.data)
}
},
watch: {
data () {
this.createVoyager()
}
},
mounted () {
this.createVoyager()
}
}
</script>

<style css src='datavoyager/build/style.css'>
</style>
2 changes: 2 additions & 0 deletions app/src/pages/explorer/chart/datavoyager/DataVoyagerPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<template src="./data-voyager-page.html"></template>
<script src="./data-voyager-page.js"></script>
64 changes: 64 additions & 0 deletions app/src/pages/explorer/chart/datavoyager/data-voyager-page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<div class="datavoyager">
<div class="utility-content__result">
<div
class="utility-gridicon"
v-if="!loading"
>
<div>
<md-button
class="md-icon-button"
@click.native.prevent="navBack"
>
<md-tooltip md-direction="bottom">
Return to chart view
</md-tooltip>
<md-icon>arrow_back</md-icon>
</md-button>
<!-- TODO: Enable save button for new chart creation -->
<md-button
class="md-icon-button"
@click.native.prevent="saveAsChart"
v-if="!isNewChart && voyagerSpec"
disabled
>
<md-tooltip md-direction="bottom">
Save current spec as new chart
</md-tooltip>
<md-icon>save</md-icon>
</md-button>
<!-- TODO: Enable select button for new chart editing -->
<md-button
class="md-icon-button"
@click.native.prevent="selectSpec"
v-if="isNewChart && voyagerSpec"
>
<md-tooltip md-direction="bottom">
Select current spec and return to Viz Editor
</md-tooltip>
<md-icon>check</md-icon>
</md-button>
</div>
</div>
</div>
<div class="viz-sample__header viz-u-mgbottom">
<span class="datavoyager-title">Data Voyager</span>
<span v-if="!isNewChart && chart && chart.title">: {{chart.title}}</span>
</div>
<div
class="loading-dialog"
style="margin: auto"
v-if="loading"
>
<spinner :loading="loading" />
</div>
<div
class="loading-dialog"
style="margin: auto"
v-else
>
<data-voyager
:data="data"
:spec.sync="voyagerSpec"
></data-voyager>
</div>
</div>
71 changes: 71 additions & 0 deletions app/src/pages/explorer/chart/datavoyager/data-voyager-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { mapGetters, mapActions, mapMutations } from 'vuex'
// import {
// copyChart,
// saveChart
// } from "@/modules/vega-chart";
import { toChartUri } from '@/modules/vega-chart'
import { querySparql, parseSparql } from '@/modules/sparql'
import DataVoyager from '@/components/explorer/DataVoyager'
import spinner from '@/components/Spinner'

export default {
data () {
return {
loading: true,
voyagerSpec: null,
specJsonEditorOpts: {
mode: 'code',
mainMenuBar: false
}
}
},
props: ['chartId'],
components: {
DataVoyager,
spinner
},
computed: {
...mapGetters('vega', ['chart']),
isNewChart () {
// TODO: Add ability to create new charts from datavoyager once new chart pipeline is set up
return false
}
},
methods: {
...mapActions('vega', ['loadChart']),
...mapMutations('vega', ['setBaseSpec']),
async loadData () {
this.loading = true
if (!this.isNewChart) {
await this.loadChart(toChartUri(this.chartId))
}
const sparqlResults = await querySparql(this.chart.query)
this.data = { values: parseSparql(sparqlResults) }
this.loading = false
},
saveAsChart () {
// TODO: add once pipeline for creating new charts is set up
},
selectSpec () {
// //TODO: Will be called from saveAsChart
// this.setBaseSpec(this.voyagerSpec)
// this.goToChartEditor()
},
goToChartView () {
this.$router.push(`/explorer/chart/view/${this.chartId}`)
},
goToChartEditor () {
// TODO: Link to chart editor once exists
},
navBack () {
if (this.isNewChart) {
this.goToChartEditor()
} else {
this.goToChartView()
}
}
},
mounted () {
this.loadData()
}
}
10 changes: 5 additions & 5 deletions app/src/pages/explorer/chart/view/vega-view-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,16 @@ export default {
}
}
},
props: ['chartId'],
computed: {
...mapGetters({
dialogBoxActive: 'dialogBox'
}),
specViewerSpec () {
return this.specViewer.includeData ? this.spec : this.chart && this.chart.baseSpec
},
pageUri () {
return toChartUri(this.$route.params.chartId)
fullChartUri () {
return toChartUri(this.chartId)
}
},
methods: {
Expand All @@ -63,7 +64,7 @@ export default {
}),
async loadVisualization () {
try {
this.chart = await loadChart(`${this.pageUri}`)
this.chart = await loadChart(`${this.fullChartUri}`)
if (this.chart.query) {
this.results = await querySparql(this.chart.query)
}
Expand All @@ -75,8 +76,7 @@ export default {
}
},
navBack (args) {
},
openVoyager () {
this.$router.push('/explorer/chart')
},
editChart () {
},
Expand Down
14 changes: 7 additions & 7 deletions app/src/pages/explorer/chart/view/vega-view.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
<md-icon>integration_instructions</md-icon>
</md-button>
</div>
<div>
<md-button disabled class="md-icon-button" @click.native.prevent="openVoyager">
<md-tooltip> View Data in Voyager </md-tooltip>
<md-icon>dynamic_form</md-icon>
</md-button>
</div>
<router-link class="md-icon-button" :to="{name: 'ChartDataVoyager', params: {chartId: this.chartId} }" v-slot="{navigate, href}" custom>
<md-button class="md-icon-button" :href="href" @click="navigate">
<md-tooltip> View Data in Voyager </md-tooltip>
<md-icon>dynamic_form</md-icon>
</md-button>
</router-link>
<div v-if="allowEdit">
<md-button disabled class="md-icon-button" @click.native.prevent="editChart">
<md-tooltip> Edit Chart </md-tooltip>
Expand Down Expand Up @@ -92,7 +92,7 @@
<template v-slot:content>
<div v-if="dialog.type=='share'">
<md-field> <label>Chart Link</label>
<md-textarea disabled v-model="pageUri"></md-textarea>
<md-textarea disabled v-model="fullChartUri"></md-textarea>
</md-field>
<div>Copy the link above to share this chart</div>
</div>
Expand Down
9 changes: 9 additions & 0 deletions app/src/router/module/explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const explorerRoutes = [
{
path: 'edit/:chartId',
name: 'ChartEdit',
props: true,
meta: { requiresAuth: false }
},
{
Expand All @@ -54,6 +55,14 @@ const explorerRoutes = [
path: 'view/:chartId',
name: 'ChartView',
component: () => import('@/pages/explorer/chart/view/VegaView.vue'),
props: true,
meta: { requiresAuth: false }
},
{
path: 'voyager/:chartId',
name: 'ChartDataVoyager',
component: () => import('@/pages/explorer/chart/datavoyager/DataVoyagerPage.vue'),
props: true,
meta: { requiresAuth: false }
}
]
Expand Down
65 changes: 65 additions & 0 deletions app/tests/unit/components/explorer/DataVoyager.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import createWrapper from '../../../jest/script/wrapper'
import { enableAutoDestroy } from '@vue/test-utils'

import DataVoyager from '@/components/explorer/DataVoyager.vue'

describe('DataVoyager.vue', () => {
// Suppress console specifically for Data Voyager tests, not globally
beforeEach(() => {
jest.spyOn(console, 'debug').mockImplementation(() => {})
jest.spyOn(console, 'warn').mockImplementation(() => {})
})

enableAutoDestroy(afterEach)

it('renders datavoyager in correct place', () => {
const wrapper = createWrapper(DataVoyager, {}, false)
const dvComponent = wrapper.findComponent('#voyager-embed > .voyager')
expect(dvComponent.exists()).toBeTruthy()
})
it('displays field names when passed data', async () => {
const wrapper = await createWrapper(DataVoyager, { props: { data } }, true)
await wrapper.vm.$nextTick() // Render data
expect(wrapper.text()).toContain('qualFieldTest')
expect(wrapper.text()).toContain('quantFieldTest')
})
it('displays data panel containing fields when passed data', async () => {
const wrapper = await createWrapper(DataVoyager, { props: { data } }, true)
await wrapper.vm.$nextTick() // Render data
const dataPanel = wrapper.findComponent('.Pane1')
expect(dataPanel.exists()).toBeTruthy()
expect(dataPanel.text()).toContain('Data')
expect(dataPanel.text()).toContain('qualFieldTest')
expect(dataPanel.text()).toContain('quantFieldTest')
})
it('displays encoding panel when passed data', async () => {
const wrapper = await createWrapper(DataVoyager, { props: { data } }, true)
await wrapper.vm.$nextTick() // Render data
const encodingPanel = wrapper.findComponent('.Pane2')
expect(encodingPanel.exists()).toBeTruthy()
expect(encodingPanel.text()).toContain('Encoding')
})
it('generates at least one example chart from data', async () => {
const wrapper = await createWrapper(DataVoyager, { props: { data } }, true)
await wrapper.vm.$nextTick() // Render data
const exampleChart = wrapper.findComponent('.chart')
expect(exampleChart.exists()).toBeTruthy()
})
})

const data = {
values: [
{
qualFieldTest: 'ABC',
quantFieldTest: 123
},
{
qualFieldTest: 'DEF',
quantFieldTest: 456
},
{
qualFieldTest: 'GHI',
quantFieldTest: 789
}
]
}

0 comments on commit 345e310

Please sign in to comment.