Allow actions on chart series (#1417)
Add optional performAction args to accept an arbitrary config and/or context. Supersedes #1392. Closes #1391. Signed-off-by: Yannick Schaus <github@schaus.net> Also-by: Łukasz Dywicki <luke@code-house.org>pull/1445/head
parent
1094d4b16d
commit
34c59ecc2d
|
@ -1,6 +1,8 @@
|
||||||
// definitions for the chart widgets
|
// definitions for the chart widgets
|
||||||
// TODO: migrate to WidgetDefinition & use helpers
|
// TODO: migrate to WidgetDefinition & use helpers
|
||||||
|
|
||||||
|
import { actionGroup, actionParams } from '../actions'
|
||||||
|
|
||||||
const positionGroup = {
|
const positionGroup = {
|
||||||
name: 'position',
|
name: 'position',
|
||||||
label: 'Position',
|
label: 'Position',
|
||||||
|
@ -366,11 +368,12 @@ export default {
|
||||||
label: 'Calendar',
|
label: 'Calendar',
|
||||||
docLink: 'https://echarts.apache.org/en/option.html#calendar',
|
docLink: 'https://echarts.apache.org/en/option.html#calendar',
|
||||||
props: {
|
props: {
|
||||||
parameterGroups: [nameDisplayGroup, componentRelationsGroup],
|
parameterGroups: [nameDisplayGroup, componentRelationsGroup, actionGroup()],
|
||||||
parameters: [
|
parameters: [
|
||||||
...positionParameters,
|
...positionParameters,
|
||||||
orientParameter,
|
orientParameter,
|
||||||
gridIndexParameter
|
gridIndexParameter,
|
||||||
|
...actionParams()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -379,9 +382,10 @@ export default {
|
||||||
label: 'Data Series',
|
label: 'Data Series',
|
||||||
docLink: 'https://echarts.apache.org/en/option.html#series',
|
docLink: 'https://echarts.apache.org/en/option.html#series',
|
||||||
props: {
|
props: {
|
||||||
parameterGroups: [],
|
parameterGroups: [actionGroup()],
|
||||||
parameters: [
|
parameters: [
|
||||||
seriesTypeParameter('gauge', 'pie')
|
seriesTypeParameter('gauge', 'pie'),
|
||||||
|
...actionParams()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -390,12 +394,13 @@ export default {
|
||||||
label: 'Time Series',
|
label: 'Time Series',
|
||||||
docLink: 'https://echarts.apache.org/en/option.html#series',
|
docLink: 'https://echarts.apache.org/en/option.html#series',
|
||||||
props: {
|
props: {
|
||||||
parameterGroups: [componentRelationsGroup],
|
parameterGroups: [componentRelationsGroup, actionGroup()],
|
||||||
parameters: [
|
parameters: [
|
||||||
...seriesParameters,
|
...seriesParameters,
|
||||||
seriesTypeParameter('line', 'bar', 'heatmap', 'scatter'),
|
seriesTypeParameter('line', 'bar', 'heatmap', 'scatter'),
|
||||||
xAxisIndexParameter,
|
xAxisIndexParameter,
|
||||||
yAxisIndexParameter
|
yAxisIndexParameter,
|
||||||
|
...actionParams()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -404,7 +409,7 @@ export default {
|
||||||
label: 'Aggregate Series',
|
label: 'Aggregate Series',
|
||||||
docLink: 'https://echarts.apache.org/en/option.html#series',
|
docLink: 'https://echarts.apache.org/en/option.html#series',
|
||||||
props: {
|
props: {
|
||||||
parameterGroups: [componentRelationsGroup],
|
parameterGroups: [componentRelationsGroup, actionGroup()],
|
||||||
parameters: [
|
parameters: [
|
||||||
...seriesParameters,
|
...seriesParameters,
|
||||||
seriesTypeParameter('line', 'bar', 'heatmap', 'scatter'),
|
seriesTypeParameter('line', 'bar', 'heatmap', 'scatter'),
|
||||||
|
@ -432,7 +437,8 @@ export default {
|
||||||
},
|
},
|
||||||
aggregationFunctionParameter,
|
aggregationFunctionParameter,
|
||||||
xAxisIndexParameter,
|
xAxisIndexParameter,
|
||||||
yAxisIndexParameter
|
yAxisIndexParameter,
|
||||||
|
...actionParams()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -441,12 +447,13 @@ export default {
|
||||||
label: 'Calendar Series',
|
label: 'Calendar Series',
|
||||||
docLink: 'https://echarts.apache.org/en/option.html#series',
|
docLink: 'https://echarts.apache.org/en/option.html#series',
|
||||||
props: {
|
props: {
|
||||||
parameterGroups: [componentRelationsGroup],
|
parameterGroups: [componentRelationsGroup, actionGroup()],
|
||||||
parameters: [
|
parameters: [
|
||||||
...seriesParameters,
|
...seriesParameters,
|
||||||
seriesTypeParameter('heatmap', 'scatter'),
|
seriesTypeParameter('heatmap', 'scatter'),
|
||||||
aggregationFunctionParameter,
|
aggregationFunctionParameter,
|
||||||
calendarIndexParameter
|
calendarIndexParameter,
|
||||||
|
...actionParams()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
v-if="ready"
|
v-if="ready"
|
||||||
:options="options"
|
:options="options"
|
||||||
class="oh-chart"
|
class="oh-chart"
|
||||||
|
@click="handleClick"
|
||||||
:class="{ 'with-tabbar': context.tab, 'with-toolbar': context.analyzer }"
|
:class="{ 'with-tabbar': context.tab, 'with-toolbar': context.analyzer }"
|
||||||
:theme="$f7.data.themeOptions.dark === 'dark' ? 'dark' : undefined" autoresize />
|
:theme="$f7.data.themeOptions.dark === 'dark' ? 'dark' : undefined" autoresize />
|
||||||
<f7-menu class="padding float-right" v-if="periodVisible">
|
<f7-menu class="padding float-right" v-if="periodVisible">
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
<script>
|
<script>
|
||||||
import mixin from '../widget-mixin'
|
import mixin from '../widget-mixin'
|
||||||
import chart from '../chart/chart-mixin'
|
import chart from '../chart/chart-mixin'
|
||||||
|
import { actionsMixin } from '../widget-actions'
|
||||||
|
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import LocalizedFormat from 'dayjs/plugin/localizedFormat'
|
import LocalizedFormat from 'dayjs/plugin/localizedFormat'
|
||||||
|
@ -62,7 +64,7 @@ import 'echarts/lib/component/calendar'
|
||||||
import ECharts from 'vue-echarts/components/ECharts'
|
import ECharts from 'vue-echarts/components/ECharts'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [mixin, chart],
|
mixins: [mixin, chart, actionsMixin],
|
||||||
components: {
|
components: {
|
||||||
'chart': ECharts
|
'chart': ECharts
|
||||||
},
|
},
|
||||||
|
@ -113,6 +115,14 @@ export default {
|
||||||
if (this.calendarPicker) this.calendarPicker.destroy()
|
if (this.calendarPicker) this.calendarPicker.destroy()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handleClick (evt) {
|
||||||
|
if (evt.seriesIndex !== undefined) {
|
||||||
|
if (this.context.component.slots && this.context.component.slots.series && Array.isArray(this.context.component.slots.series) && this.context.component.slots.series.length) {
|
||||||
|
let series = this.context.component.slots.series[evt.seriesIndex]
|
||||||
|
this.performAction(evt.event, null, series.config, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
pickFixedStartDate (evt) {
|
pickFixedStartDate (evt) {
|
||||||
const self = this
|
const self = this
|
||||||
const value = this.startTime.toDate()
|
const value = this.startTime.toDate()
|
||||||
|
|
|
@ -28,14 +28,34 @@ export const actionsMixin = {
|
||||||
})).open()
|
})).open()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
performAction (evt, prefix) {
|
/**
|
||||||
if (!this.context || !this.config) return
|
* Performs an action determined by config parameters.
|
||||||
const actionPropsParameterGroup = this.config[((prefix) ? prefix + '_' : '') + 'actionPropsParameterGroup']
|
*
|
||||||
const actionConfig = (actionPropsParameterGroup) ? this.evaluateExpression('$props', this.context.props) : this.config
|
* If no prefix is specified, will use the parameter "action" and other parameters beginning with "action"
|
||||||
|
* If a prefix is specified, the parameters considered will be "prefix_action*"
|
||||||
|
*
|
||||||
|
* Instead of "[prefix_]action" and others, "[prefix_]actionPropsParameterGroup" can be provided.
|
||||||
|
* The value must match the name of a parameter group with the context set to "actions".
|
||||||
|
* The actual prefix of the parameters will then match the name of the group with the term "action" removed.
|
||||||
|
* For example, for a "dblclickAction" parameter group, the action parameters will be "dblclick_action*".
|
||||||
|
* This allows custom widget designers to offer actions parameters to configure their widget.
|
||||||
|
*
|
||||||
|
* @param {Event} evt the event (e.g. "click") at the origin of the action
|
||||||
|
* @param {String} prefix the prefix for the parameter group and associated parameters (see below)
|
||||||
|
* @param {Object} config the config object containing the parameters to use, will use `this.config` if unset
|
||||||
|
* @param {Object} context the context to use, will use `this.context` if unset
|
||||||
|
* @returns {Boolean?} true if the action was performed, otherwise undefined
|
||||||
|
*/
|
||||||
|
performAction (evt, prefix, config, context) {
|
||||||
|
if (!context) context = this.context
|
||||||
|
if (!config) config = this.config
|
||||||
|
if (!config || !context) return
|
||||||
|
const actionPropsParameterGroup = config[((prefix) ? prefix + '_' : '') + 'actionPropsParameterGroup']
|
||||||
|
const actionConfig = (actionPropsParameterGroup) ? this.evaluateExpression('$props', context.props) : config
|
||||||
prefix = (actionPropsParameterGroup) ? actionPropsParameterGroup.replace(/action/gi, '') : prefix
|
prefix = (actionPropsParameterGroup) ? actionPropsParameterGroup.replace(/action/gi, '') : prefix
|
||||||
prefix = (prefix) ? prefix += '_' : ''
|
prefix = (prefix) ? prefix += '_' : ''
|
||||||
const action = actionConfig[prefix + 'action']
|
const action = actionConfig[prefix + 'action']
|
||||||
if (this.context.editmode) {
|
if (context.editmode) {
|
||||||
this.showActionFeedback(prefix, actionConfig, `Action '${action}' not performed while in edit mode`)
|
this.showActionFeedback(prefix, actionConfig, `Action '${action}' not performed while in edit mode`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -65,8 +85,8 @@ export const actionsMixin = {
|
||||||
const actionToggleItem = actionConfig[prefix + 'actionItem']
|
const actionToggleItem = actionConfig[prefix + 'actionItem']
|
||||||
const actionToggleCommand = actionConfig[prefix + 'actionCommand']
|
const actionToggleCommand = actionConfig[prefix + 'actionCommand']
|
||||||
const actionToggleCommandAlt = actionConfig[prefix + 'actionCommandAlt']
|
const actionToggleCommandAlt = actionConfig[prefix + 'actionCommandAlt']
|
||||||
const state = this.context.store[actionToggleItem].state
|
const state = context.store[actionToggleItem].state
|
||||||
let cmd = this.context.store[actionToggleItem].state === actionToggleCommand ? actionToggleCommandAlt : actionToggleCommand
|
let cmd = context.store[actionToggleItem].state === actionToggleCommand ? actionToggleCommandAlt : actionToggleCommand
|
||||||
// special behavior for Color, Dimmer
|
// special behavior for Color, Dimmer
|
||||||
if (actionToggleCommand === 'OFF' && state.split(',').length === 3 && parseInt(state.split(',')[2]) === 0) cmd = actionToggleCommandAlt
|
if (actionToggleCommand === 'OFF' && state.split(',').length === 3 && parseInt(state.split(',')[2]) === 0) cmd = actionToggleCommandAlt
|
||||||
if (actionToggleCommand === 'ON' && state.split(',').length === 3 && parseInt(state.split(',')[2]) > 0) cmd = actionToggleCommandAlt
|
if (actionToggleCommand === 'ON' && state.split(',').length === 3 && parseInt(state.split(',')[2]) > 0) cmd = actionToggleCommandAlt
|
||||||
|
@ -227,7 +247,7 @@ export const actionsMixin = {
|
||||||
case 'variable':
|
case 'variable':
|
||||||
const actionVariable = actionConfig[prefix + 'actionVariable']
|
const actionVariable = actionConfig[prefix + 'actionVariable']
|
||||||
const actionVariableValue = actionConfig[prefix + 'actionVariableValue']
|
const actionVariableValue = actionConfig[prefix + 'actionVariableValue']
|
||||||
this.$set(this.context.vars, actionVariable, actionVariableValue)
|
this.$set(context.vars, actionVariable, actionVariableValue)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
console.log('Invalid action: ' + action)
|
console.log('Invalid action: ' + action)
|
||||||
|
|
Loading…
Reference in New Issue