mirror of
https://github.com/h-sphere/sql-seal-charts.git
synced 2026-07-22 05:37:34 +00:00
feat: adding advanced mode
This commit is contained in:
parent
732577fae5
commit
37f746b72c
6 changed files with 870 additions and 777 deletions
33
docs/advanced-mode.md
Normal file
33
docs/advanced-mode.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Advanced Mode
|
||||
You can turn on Advanced mode which will enable you to write pure JavaScript. You have access to your query result and helper functions inside it so you can use it to transform your data, perform additional logic, etc.
|
||||
In advanced mode you need to return manually the object that will be used as a chart configuration in the end.
|
||||
|
||||
## Example
|
||||
|
||||
More advanced examples to be added later.
|
||||
|
||||
```sqlseal
|
||||
ADVANCED MODE
|
||||
-- now you can use all JavaScript syntax to your heart content
|
||||
CHART
|
||||
const values = (new Array(5)).map((_, i) => i)
|
||||
return {
|
||||
tooltip: {},
|
||||
legend: {
|
||||
data: ['sales']
|
||||
},
|
||||
xAxis: {
|
||||
data: ['Shirts', 'Cardigans', 'Chiffons', 'Pants', 'Heels', 'Socks']
|
||||
},
|
||||
yAxis: {},
|
||||
series: [
|
||||
{
|
||||
name: 'sales',
|
||||
type: 'bar',
|
||||
data: [5, 20, 36, 10, 10, 20]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
SELECT * FROM files
|
||||
```
|
||||
24
package.json
24
package.json
|
|
@ -31,29 +31,29 @@
|
|||
"@types/acorn": "^6.0.4",
|
||||
"@types/estree": "^1.0.6",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^22.12.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.22.0",
|
||||
"@typescript-eslint/parser": "^8.22.0",
|
||||
"builtin-modules": "^4.0.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"@types/node": "^22.13.10",
|
||||
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||
"@typescript-eslint/parser": "^8.26.1",
|
||||
"builtin-modules": "^5.0.0",
|
||||
"esbuild": "^0.25.1",
|
||||
"jest": "^29.7.0",
|
||||
"obsidian": "^1.7.2",
|
||||
"ts-jest": "^29.2.5",
|
||||
"obsidian": "^1.8.7",
|
||||
"ts-jest": "^29.2.6",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.7.3"
|
||||
"typescript": "^5.8.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hypersphere/sqlseal": "^0.21.0",
|
||||
"@hypersphere/sqlseal": "^0.28.0",
|
||||
"@types/leaflet": "^1.9.16",
|
||||
"@types/lodash": "^4.17.15",
|
||||
"@types/lodash": "^4.17.16",
|
||||
"@vanakat/plugin-api": "^0.2.1",
|
||||
"acorn": "^8.14.0",
|
||||
"acorn": "^8.14.1",
|
||||
"echarts": "^5.6.0",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"json5": "^2.2.3",
|
||||
"lodash": "^4.17.21",
|
||||
"vitepress": "^1.6.3",
|
||||
"vue": "^3.5.13",
|
||||
"zod": "^3.24.1"
|
||||
"zod": "^3.24.2"
|
||||
}
|
||||
}
|
||||
1531
pnpm-lock.yaml
1531
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -3,6 +3,8 @@ import { parseCode } from "./utils/configParser";
|
|||
import { prepareDataVariables } from "./utils/prepareDataVariables";
|
||||
import * as echarts from 'echarts';
|
||||
import type { RendererConfig } from "@hypersphere/sqlseal";
|
||||
import { ViewDefinition } from "@hypersphere/sqlseal/dist/src/grammar/parser";
|
||||
import { parseCodeAdvanced } from "./utils/advancedParser";
|
||||
|
||||
interface Config {
|
||||
config: string
|
||||
|
|
@ -13,21 +15,46 @@ export class ChartRenderer implements RendererConfig {
|
|||
constructor(private readonly app: App) {
|
||||
}
|
||||
|
||||
get viewDefinition(): ViewDefinition {
|
||||
return {
|
||||
argument: 'javascriptTemplate',
|
||||
name: 'chart',
|
||||
singleLine: false
|
||||
}
|
||||
}
|
||||
|
||||
get rendererKey() {
|
||||
return 'chart'
|
||||
}
|
||||
|
||||
validateConfig(config: string): Config {
|
||||
return { config }
|
||||
return { config: config.trim() }
|
||||
}
|
||||
|
||||
render(config: Config, el: HTMLElement) {
|
||||
let isRendered: boolean = false
|
||||
let chart: echarts.ECharts | null = null
|
||||
return {
|
||||
render: ({ columns, data }: { columns: string[], data: Record<string, unknown>[]}) => {
|
||||
render: ({ columns, data, flags }: { columns: string[], data: Record<string, unknown>[], flags: Record<string, boolean> }) => {
|
||||
|
||||
const isAdvancedMode = !!(flags?.isAdvancedMode)
|
||||
|
||||
if (config.config[0] !== '{' && !isAdvancedMode) {
|
||||
throw new Error('To process JavaScript, set ADVANCED MODE flag')
|
||||
}
|
||||
const { functions, variables } = prepareDataVariables({ columns, data })
|
||||
const parsedConfig = parseCode(config.config, functions, variables)
|
||||
|
||||
let parsedConfig: Object = {}
|
||||
if (isAdvancedMode) {
|
||||
try {
|
||||
parsedConfig = parseCodeAdvanced({ functions, variables }, config.config)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
parsedConfig = parseCode(config.config, functions, variables) as Object
|
||||
}
|
||||
if (!parsedConfig || typeof parsedConfig !== 'object') {
|
||||
throw new Error('Issue with parsing config')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,5 +13,9 @@ export default class SQLSealCharts extends Plugin {
|
|||
const api = pluginApi('sqlseal') as SQLSealRegisterApi
|
||||
const registar = api.registerForPlugin(this)
|
||||
registar.registerView('sqlseal-charts', new ChartRenderer(this.app))
|
||||
|
||||
if (api.apiVersion >= 2) {
|
||||
registar.registerFlag({ key: 'isAdvancedMode', name: 'ADVANCED MODE' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
src/utils/advancedParser.ts
Normal file
22
src/utils/advancedParser.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { uniqBy } from "lodash"
|
||||
|
||||
type Params = {
|
||||
functions: Record<string, any>,
|
||||
variables: Record<string, any>
|
||||
}
|
||||
|
||||
export const parseCodeAdvanced = ({ functions, variables }: Params, code: string) => {
|
||||
const { keys, values } = uniqBy([
|
||||
...Object.entries(functions),
|
||||
...Object.entries({
|
||||
data: variables.data,
|
||||
columns: variables.columns
|
||||
})
|
||||
], 0).reduce(({ keys, values}, [key, value]) => ({
|
||||
keys: [...keys, key],
|
||||
values: [...values, value]
|
||||
}), { keys: [], values: []})
|
||||
const fn = new Function(...keys, code)
|
||||
|
||||
return fn(...values)
|
||||
}
|
||||
Loading…
Reference in a new issue