Skip to content

Commit

Permalink
[gui2] Language Server binary protocol, and loading of visualization …
Browse files Browse the repository at this point in the history
…data (#7873)

- Depends on #7773.

- Implements binary WebSocket protocol (data protocol)
- Performs some editor initialization (the bare minimum so that visualizations work)
- Adds event handlers to receive visualization data updates

# Important Notes
None
  • Loading branch information
somebody1234 authored Oct 7, 2023
1 parent a90af9f commit 44f2f42
Show file tree
Hide file tree
Showing 55 changed files with 4,107 additions and 624 deletions.
1 change: 1 addition & 0 deletions app/gui2/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ coverage

# Editor directories and files
.vscode/*
!.vscode/settings.json
!.vscode/extensions.json
.idea
*.suo
Expand Down
3 changes: 3 additions & 0 deletions app/gui2/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"prettier.prettierPath": "../../node_modules/prettier/index.cjs"
}
1 change: 0 additions & 1 deletion app/gui2/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ declare module 'builtins' {
export const VisualizationContainer: typeof import('@/components/VisualizationContainer.vue').default
export const useVisualizationConfig: typeof import('@/providers/visualizationConfig').useVisualizationConfig
export const defineKeybinds: typeof import('@/util/shortcuts').defineKeybinds
export const d3: typeof import('d3')
}
1 change: 1 addition & 0 deletions app/gui2/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const conf = [
rules: {
camelcase: [1, { ignoreImports: true }],
'no-inner-declarations': 0,
'vue/attribute-hyphenation': [2, 'never'],
'vue/v-on-event-hyphenation': [2, 'never'],
'@typescript-eslint/no-unused-vars': [
1,
Expand Down
6 changes: 0 additions & 6 deletions app/gui2/node.env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,3 @@ module 'tailwindcss/nesting' {
declare const plugin: PluginCreator<unknown>
export default plugin
}

// This is an augmentation to the built-in `ImportMeta` interface.
// This file MUST NOT contain any top-level imports.
interface ImportMeta {
vitest: typeof import('vitest') | undefined
}
3 changes: 1 addition & 2 deletions app/gui2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"fast-diff": "^1.3.0",
"hash-sum": "^2.0.0",
"isomorphic-ws": "^5.0.0",
"lib0": "^0.2.83",
"lib0": "^0.2.85",
"magic-string": "^0.30.3",
"murmurhash": "^2.0.1",
"pinia": "^2.1.6",
Expand All @@ -43,7 +43,6 @@
"sha3": "^2.1.4",
"sucrase": "^3.34.0",
"vue": "^3.3.4",
"vue-codemirror": "^6.1.1",
"ws": "^8.13.0",
"y-codemirror.next": "^0.3.2",
"y-protocols": "^1.0.5",
Expand Down
52 changes: 27 additions & 25 deletions app/gui2/public/visualizations/ScatterplotVisualization.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ import { defineKeybinds } from 'builtins'
export const name = 'Scatterplot'
export const inputType = 'Standard.Table.Data.Table.Table | Standard.Base.Data.Vector.Vector'
const DEFAULT_LIMIT = 1024
export const defaultPreprocessor = [
'Standard.Visualization.Scatter_Plot',
'process_to_json_text',
'Nothing',
DEFAULT_LIMIT.toString(),
]
const bindings = defineKeybinds('scatterplot-visualization', {
zoomIn: ['Mod+Z'],
Expand Down Expand Up @@ -68,7 +75,7 @@ enum ScaleType {
interface AxisConfiguration {
label: string
scale: ScaleType
scale?: ScaleType
}
interface AxesConfiguration {
Expand All @@ -84,8 +91,10 @@ interface Color {
</script>

<script setup lang="ts">
import { d3 } from 'builtins'
import { computed, onMounted, ref, watch, watchEffect, watchPostEffect } from 'vue'
import { computed, ref, watch, watchEffect, watchPostEffect } from 'vue'
import * as d3 from 'd3'
import FindIcon from './icons/find.svg'
import ShowAllIcon from './icons/show_all.svg'
Expand All @@ -106,12 +115,9 @@ const POINT_LABEL_PADDING_X_PX = 7
const POINT_LABEL_PADDING_Y_PX = 2
const ANIMATION_DURATION_MS = 400
const VISIBLE_POINTS = 'visible'
const DEFAULT_LIMIT = 1024
const ACCENT_COLOR: Color = { red: 78, green: 165, blue: 253 }
const SIZE_SCALE_MULTIPLER = 100
const FILL_COLOR = `rgba(${ACCENT_COLOR.red * 255},${ACCENT_COLOR.green * 255},${
ACCENT_COLOR.blue * 255
},0.8)`
const FILL_COLOR = `rgba(${ACCENT_COLOR.red},${ACCENT_COLOR.green},${ACCENT_COLOR.blue},0.8)`
const ZOOM_EXTENT = [0.5, 20] satisfies d3.BrushSelection
const RIGHT_BUTTON = 2
Expand Down Expand Up @@ -201,18 +207,18 @@ const margin = computed(() => {
return { top: 10, right: 10, bottom: 35, left: 55 }
}
})
const width = ref(Math.max(config.value.width ?? 0, config.value.nodeSize.x))
watchPostEffect(() => {
width.value = config.value.fullscreen
const width = computed(() =>
config.value.fullscreen
? containerNode.value?.parentElement?.clientWidth ?? 0
: Math.max(config.value.width ?? 0, config.value.nodeSize.x)
})
const height = ref(config.value.height ?? (config.value.nodeSize.x * 3) / 4)
watchPostEffect(() => {
height.value = config.value.fullscreen
: Math.max(config.value.width ?? 0, config.value.nodeSize.x),
)
const height = computed(() =>
config.value.fullscreen
? containerNode.value?.parentElement?.clientHeight ?? 0
: config.value.height ?? (config.value.nodeSize.x * 3) / 4
})
: config.value.height ?? (config.value.nodeSize.x * 3) / 4,
)
const boxWidth = computed(() => Math.max(0, width.value - margin.value.left - margin.value.right))
const boxHeight = computed(() => Math.max(0, height.value - margin.value.top - margin.value.bottom))
const xTicks = computed(() => boxWidth.value / 40)
Expand All @@ -229,17 +235,15 @@ const yLabelLeft = computed(
)
const yLabelTop = computed(() => -margin.value.left + 15)
function updatePreprocessor() {
watchEffect(() => {
emit(
'update:preprocessor',
'Standard.Visualization.Scatter_Plot',
'process_to_json_text',
bounds.value == null ? 'Nothing' : '[' + bounds.value.join(',') + ']',
limit.value.toString(),
)
}
onMounted(updatePreprocessor)
})
watchEffect(() => (focus.value = data.value.focus))
Expand Down Expand Up @@ -409,7 +413,6 @@ function zoomToSelected() {
const yMin = yScale_.invert(yMinRaw)
const yMax = yScale_.invert(yMaxRaw)
bounds.value = [xMin, yMin, xMax, yMax]
updatePreprocessor()
xDomain.value = [xMin, xMax]
yDomain.value = [yMin, yMax]
}
Expand All @@ -435,7 +438,7 @@ function matchShape(d: Point) {
* @param axis Axis information as received in the visualization update.
* @returns D3 scale. */
function axisD3Scale(axis: AxisConfiguration | undefined) {
return axis != null ? SCALE_TO_D3_SCALE[axis.scale]() : d3.scaleLinear()
return axis?.scale != null ? SCALE_TO_D3_SCALE[axis.scale]() : d3.scaleLinear()
}
watchEffect(() => {
Expand Down Expand Up @@ -522,7 +525,6 @@ function showAll() {
extremesAndDeltas.value.yMin - extremesAndDeltas.value.paddingY,
extremesAndDeltas.value.yMax + extremesAndDeltas.value.paddingY,
]
updatePreprocessor()
endBrushing()
}
Expand All @@ -539,7 +541,7 @@ useEvent(document, 'scroll', endBrushing)
</script>

<template>
<VisualizationContainer :below-toolbar="true">
<VisualizationContainer :belowToolbar="true">
<template #toolbar>
<button class="image-button active">
<img :src="ShowAllIcon" alt="Fit all" @pointerdown="showAll" />
Expand Down
6 changes: 6 additions & 0 deletions app/gui2/public/visualizations/template.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<script lang="ts">
export const name = '<name here>'
export const inputType = '<allowed input type(s) here>'
// Optional:
export const defaultPreprocessor = [
'<module path here>',
'<method name here>',
'<optional args here>',
]
interface Data {
dataType: 'here'
Expand Down
Loading

0 comments on commit 44f2f42

Please sign in to comment.