Skip to content

Commit

Permalink
feature/flipperPlotter (#37)
Browse files Browse the repository at this point in the history
* feat: Create pulse plotter from Flipper

* feat: Add alias for composables

* feat: Add composable useNumberOnly

* fix: Deleted unnecessary code

* refactor: Changed syntax

* feat: Added a limit on entering numbers

* feat: Added destroy worker when leaving the page

---------

Co-authored-by: Maxim Lyubimov <[email protected]>
  • Loading branch information
mlyubimov and mlyubimov authored Oct 8, 2023
1 parent 36cace9 commit 4265a19
Show file tree
Hide file tree
Showing 18 changed files with 3,045 additions and 45 deletions.
1 change: 1 addition & 0 deletions frontend/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
/node_modules
.eslintrc.js
babel.config.js
quasar.conf.js
21 changes: 21 additions & 0 deletions frontend/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"arrowParens": "always",
"bracketSameLine": false,
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"endOfLine": "lf",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxSingleQuote": true,
"printWidth": 80,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": false,
"singleAttributePerLine": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": false,
"vueIndentScriptAndStyle": false
}
6 changes: 6 additions & 0 deletions frontend/jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
"boot/*": [
"src/boot/*"
],
"util/*": [
"src/util/*"
],
"composables/*": [
"src/composables/*"
],
"vue$": [
"node_modules/vue/dist/vue.runtime.esm-bundler.js"
]
Expand Down
4 changes: 4 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"private": true,
"scripts": {
"lint": "eslint --ext .js,.vue ./",
"lint-fix": "eslint --fix --ext .js,.vue ./",
"format": "prettier --write \"**/*.{js,ts,vue,scss,sass,css,html,md,json}\" --ignore-path .eslintignore --config .prettierrc.json && npm run lint-fix",
"dev/web": "quasar dev",
"dev/electron": "quasar dev -m electron",
"build": "PRODUCTION=TRUE quasar build -m spa",
Expand All @@ -17,9 +19,11 @@
"dependencies": {
"@quasar/extras": "^1.14.0",
"core-js": "^3.6.5",
"d3": "^7.8.5",
"loglevel": "^1.8.0",
"nanoevents": "^6.0.2",
"pako": "^2.0.4",
"prettier": "^3.0.3",
"protobufjs": "~6.11.2",
"quasar": "^2.7.1",
"semver": "^7.3.6",
Expand Down
7 changes: 6 additions & 1 deletion frontend/quasar.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* eslint-env node */
const ESLintPlugin = require('eslint-webpack-plugin')
const { configure } = require('quasar/wrappers')
const path = require('node:path')

module.exports = configure(function (ctx) {
return {
Expand Down Expand Up @@ -75,7 +76,11 @@ module.exports = configure(function (ctx) {
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpack (chain) {
chain.plugin('eslint-webpack-plugin')
.use(ESLintPlugin, [{ extensions: ['js', 'vue'] }])
.use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]),
chain.resolve.alias
.set('util', path.resolve(__dirname, './src/util'))
chain.resolve.alias
.set('composables', path.resolve(__dirname, './src/composables'))
}
},

Expand Down
116 changes: 116 additions & 0 deletions frontend/src/components/FlipperPlotter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<template>
<div id="flipperPlotter" class="full-width q-mb-md" />
<div class="full-width">
<div class="row q-col-gutter-md q-mb-md">
<q-select
class="col-1"
v-model="currentSlicer.modulation"
:options="slicerOptions"
option-value="value"
option-label="text"
emit-value
label="Slicer"
/>
<q-input
class="col-1"
v-model.number.trim="currentSlicer.short"
@keypress="useNumbersOnly"
type="text"
label="Short"
/>
<q-input
class="col-1"
v-model.number.trim="currentSlicer.long"
@keypress="useNumbersOnly"
type="text"
label="Long"
/>
<q-input
class="col-1"
v-model.number.trim="currentSlicer.sync"
@keypress="useNumbersOnly"
type="text"
label="Sync"
/>
<q-input
class="col-1"
v-model.number.trim="currentSlicer.gap"
@keypress="useNumbersOnly"
type="text"
label="Gap"
/>
<div class="col-2 flex">
<q-btn
color="primary"
icon="content_cut"
label="Slice"
size="md"
unelevated
@click="onSlice"
/>
</div>
</div>
<div class="column">
<div ref="timings" class="q-mb-md" />
<div ref="bits" />
</div>
</div>
</template>

<script setup>
import { onMounted, ref, watch, defineProps, onBeforeUnmount } from 'vue'
import { FlipperPlotter } from 'util/flipperPlotter/flipperPlotter.js'
import { FlipperPlotterOffscreen } from 'util/flipperPlotter/flipperPlotterOffscreen.js'
import { useNumbersOnly } from 'composables/useNumberOnly.js'
const props = defineProps(['data', 'offscreen'])
const timings = ref(null)
const bits = ref(null)
const plot = ref(null)
const slicerOptions = ref(null)
const currentSlicer = ref({
modulation: '',
short: 0,
long: 0,
sync: 0,
gap: 0
})
const onSlice = () => {
plot.value.setSlicer(currentSlicer.value)
}
const draw = () => {
const config = {
data: props.data,
timings: timings.value,
messages: bits.value
}
if (props.offscreen) {
plot.value = new FlipperPlotterOffscreen(config)
} else {
plot.value = new FlipperPlotter(config)
}
slicerOptions.value = plot.value.slicerOptions
currentSlicer.value = plot.value.slicer
}
onMounted(() => {
draw()
})
watch(
() => props.data,
() => {
plot.value.destroy()
draw()
}
)
onBeforeUnmount(() => {
plot.value.destroy()
})
</script>
8 changes: 8 additions & 0 deletions frontend/src/composables/useNumberOnly.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function useNumbersOnly (evt) {
const charCode = (evt.which) ? evt.which : evt.keyCode
if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
evt.preventDefault()
} else {
return true
}
}
116 changes: 72 additions & 44 deletions frontend/src/pages/Pulseplot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
style="min-width: 200px;"
/>

<div class="pulseplot fit position-relative" v-show="!flags.wrongFileType">
<FlipperPlotter v-if="plot" :data="data" :offscreen="flags.offscreenCanvasSupported"/>

<!-- <div class="pulseplot fit position-relative" v-show="!flags.wrongFileType">
<q-scroll-area
ref="scrollAreaRef"
v-if="plot"
Expand Down Expand Up @@ -98,18 +100,23 @@
</div>
<div class="pulseplot-timings overflow-auto q-py-sm"></div>
<div class="pulseplot-messages q-py-sm" style="word-break: break-all;"></div>
</div>
</div> -->
</q-page>
</template>

<script>
import { defineComponent, ref } from 'vue'
import { Pulseplot as PulseplotOffscreen } from '../util/pulseplot/pulseplot-offscreen'
import { Pulseplot } from '../util/pulseplot/pulseplot'
// import { Pulseplot as PulseplotOffscreen } from '../util/pulseplot/pulseplot-offscreen'
// import { Pulseplot } from '../util/pulseplot/pulseplot'
import FlipperPlotter from 'src/components/FlipperPlotter.vue'
export default defineComponent({
name: 'Pulseplot',
components: {
FlipperPlotter
},
props: {
passedFile: Object
},
Expand Down Expand Up @@ -169,7 +176,7 @@ export default defineComponent({
watch: {
uploadedFile (newFile, oldFile) {
if (this.plot) {
this.plot.destroy()
// this.plot.destroy()
}
this.flags.wrongFileType = false
this.signals = null
Expand All @@ -179,7 +186,7 @@ export default defineComponent({
currentSignal (newSignal, oldSignal) {
if (newSignal) {
if (this.plot) {
this.plot.destroy()
// this.plot.destroy()
}
this.data = {
centerfreq_Hz: newSignal.frequency,
Expand Down Expand Up @@ -349,43 +356,44 @@ export default defineComponent({
},
draw () {
const config = {
parent: '.pulseplot',
data: this.data,
height: 300
}
if (this.plot) {
this.plot.destroy()
this.prevScroll = null
this.nextVanityScroll = {
percentage: null,
position: null
}
const oldCanvas = document.querySelector('.pulseplot-canvas')
oldCanvas.remove()
const canvas = document.createElement('canvas')
canvas.classList.add('pulseplot-canvas')
canvas.style.imageRendering = 'pixelated'
document.querySelector('.zoom-controls').before(canvas)
}
if (this.flags.offscreenCanvasSupported) {
this.plot = new PulseplotOffscreen(config)
} else {
this.plot = new Pulseplot(config)
}
// console.log(this.plot)
this.plot.enableScrollZoom()
if (this.plot.slicer.name !== 'No clue...' && this.plot.slicer.modulation) {
this.slicer.modulation = this.plot.slicer.modulation
this.slicer.short = this.plot.slicer.short || 0
this.slicer.long = this.plot.slicer.long || 0
this.slicer.sync = this.plot.slicer.sync || 0
this.slicer.gap = this.plot.slicer.gap || 0
this.setSlicer()
}
this.plot = true
// const config = {
// parent: '.pulseplot',
// data: this.data,
// height: 300
// }
// if (this.plot) {
// this.plot.destroy()
// this.prevScroll = null
// this.nextVanityScroll = {
// percentage: null,
// position: null
// }
// const oldCanvas = document.querySelector('.pulseplot-canvas')
// oldCanvas.remove()
// const canvas = document.createElement('canvas')
// canvas.classList.add('pulseplot-canvas')
// canvas.style.imageRendering = 'pixelated'
// document.querySelector('.zoom-controls').before(canvas)
// }
// if (this.flags.offscreenCanvasSupported) {
// this.plot = new PulseplotOffscreen(config)
// } else {
// this.plot = new Pulseplot(config)
// }
// // console.log(this.plot)
// this.plot.enableScrollZoom()
// if (this.plot.slicer.name !== 'No clue...' && this.plot.slicer.modulation) {
// this.slicer.modulation = this.plot.slicer.modulation
// this.slicer.short = this.plot.slicer.short || 0
// this.slicer.long = this.plot.slicer.long || 0
// this.slicer.sync = this.plot.slicer.sync || 0
// this.slicer.gap = this.plot.slicer.gap || 0
// this.setSlicer()
// }
},
setSlicer () {
Expand All @@ -408,13 +416,32 @@ export default defineComponent({
} else {
const dy = e.verticalPosition - this.prevScroll.verticalPosition
const dx = e.horizontalPosition - this.prevScroll.horizontalPosition
this.prevScroll = e
if (dx !== 0) {
this.plot.scroll = e.horizontalPosition - 10
}
if (dy !== 0 && dy !== this.zoomLimit.max) {
const val = (this.zoomLimit.max - e.verticalPosition) > 0 ? this.zoomLimit.max - e.verticalPosition : this.zoomLimit.min
this.zoom({ val })
let plotZoom
if (this.sliderZoom < 100) {
// this.scrollAreaRef.setScrollPosition('vertical', plotZoom)
if (dy < 0) {
plotZoom = this.plot.zoom * 1.1
// plotZoom = val * 0.1
} else {
plotZoom = this.plot.zoom * 0.9
// plotZoom = val * 1.1
}
} else {
plotZoom = val
}
// console.log(e, this.zoomLimit.max - e.verticalPosition, plotZoom, this.plot.zoom)
this.zoom({ val: plotZoom })
} else {
this.plot.redrawCanvas()
}
Expand All @@ -433,6 +460,7 @@ export default defineComponent({
} else if (val) {
result = val
}
if (result <= this.zoomLimit.min) {
this.plot.zoom = this.zoomLimit.min
} else if (result >= this.zoomLimit.max) {
Expand Down
Loading

0 comments on commit 4265a19

Please sign in to comment.