From 740348eea4726b712d451fa643579f7db8821ce7 Mon Sep 17 00:00:00 2001
From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com>
Date: Thu, 14 Sep 2023 15:53:57 +0200
Subject: [PATCH 01/37] feat: add an advanced mode to bar chart
---
src/app/js/formats/chartsUtils.js | 16 +
.../component/bar-chart/BarChartAdmin.js | 501 ++++++++++--------
.../component/bar-chart/BarChartView.js | 24 +-
.../js/formats/vega-lite/models/BarChart.js | 63 ++-
4 files changed, 367 insertions(+), 237 deletions(-)
diff --git a/src/app/js/formats/chartsUtils.js b/src/app/js/formats/chartsUtils.js
index 8a0653880..121bf2cfd 100644
--- a/src/app/js/formats/chartsUtils.js
+++ b/src/app/js/formats/chartsUtils.js
@@ -73,3 +73,19 @@ export const lodexOrderToIdOrder = orderBy => {
return INVALID_VALUE;
}
};
+
+/**
+ * Convert text value to code value
+ * @param direction{'vertical' | 'horizontal'}
+ * @returns {number}
+ */
+export const lodexDirectionToIdDirection = direction => {
+ switch (direction) {
+ case 'vertical':
+ return AXIS_VERTICAL;
+ case 'horizontal':
+ return AXIS_HORIZONTAL;
+ default:
+ return INVALID_VALUE;
+ }
+};
diff --git a/src/app/js/formats/vega-lite/component/bar-chart/BarChartAdmin.js b/src/app/js/formats/vega-lite/component/bar-chart/BarChartAdmin.js
index 09d4c4829..a4d566585 100644
--- a/src/app/js/formats/vega-lite/component/bar-chart/BarChartAdmin.js
+++ b/src/app/js/formats/vega-lite/component/bar-chart/BarChartAdmin.js
@@ -1,4 +1,4 @@
-import React, { Component } from 'react';
+import React, { useEffect, useMemo } from 'react';
import PropTypes from 'prop-types';
import {
TextField,
@@ -6,6 +6,9 @@ import {
Checkbox,
FormControlLabel,
Box,
+ Switch,
+ FormGroup,
+ Button,
} from '@mui/material';
import translate from 'redux-polyglot/translate';
@@ -15,12 +18,22 @@ import RoutineParamsAdmin from '../../../shared/RoutineParamsAdmin';
import ColorPickerParamsAdmin from '../../../shared/ColorPickerParamsAdmin';
import { MULTICHROMATIC_DEFAULT_COLORSET } from '../../../colorUtils';
import ToolTips from '../../../shared/ToolTips';
+import BarChart from '../../models/BarChart';
+import {
+ AXIS_X,
+ AXIS_Y,
+ lodexDirectionToIdDirection,
+ lodexOrderToIdOrder,
+ lodexScaleToIdScale,
+} from '../../../chartsUtils';
export const defaultArgs = {
params: {
maxSize: 200,
orderBy: 'value/asc',
},
+ advanceMode: false,
+ advanceModeSpec: null,
colors: MULTICHROMATIC_DEFAULT_COLORSET,
axisRoundValue: true,
diagonalCategoryAxis: false,
@@ -35,251 +48,317 @@ export const defaultArgs = {
barSize: 20,
};
-class BarChartAdmin extends Component {
- static propTypes = {
- args: PropTypes.shape({
- params: PropTypes.shape({
- maxSize: PropTypes.number,
- maxValue: PropTypes.number,
- minValue: PropTypes.number,
- orderBy: PropTypes.string,
- }),
- colors: PropTypes.string,
- axisRoundValue: PropTypes.bool,
- diagonalCategoryAxis: PropTypes.bool,
- diagonalValueAxis: PropTypes.bool,
- scale: PropTypes.oneOf(['log', 'linear']),
- direction: PropTypes.oneOf(['horizontal', 'vertical']),
- barSize: PropTypes.number,
- tooltip: PropTypes.bool,
- tooltipCategory: PropTypes.string,
- tooltipValue: PropTypes.string,
- labels: PropTypes.bool,
- labelOverlap: PropTypes.bool,
- }),
- onChange: PropTypes.func.isRequired,
- p: polyglotPropTypes.isRequired,
- showMaxSize: PropTypes.bool.isRequired,
- showMaxValue: PropTypes.bool.isRequired,
- showMinValue: PropTypes.bool.isRequired,
- showOrderBy: PropTypes.bool.isRequired,
+const BarChartAdmin = props => {
+ const {
+ p: polyglot,
+ args,
+ showMaxSize,
+ showMaxValue,
+ showMinValue,
+ showOrderBy,
+ } = props;
+ const {
+ advanceMode,
+ advanceModeSpec,
+ params,
+ tooltip,
+ tooltipCategory,
+ tooltipValue,
+ labels,
+ barSize,
+ diagonalCategoryAxis,
+ diagonalValueAxis,
+ scale,
+ direction,
+ axisRoundValue,
+ labelOverlap,
+ } = args;
+
+ const colors = useMemo(() => {
+ return args.colors || defaultArgs.colors;
+ }, [args.colors]);
+
+ const spec = useMemo(() => {
+ if (!advanceMode) {
+ return null;
+ }
+
+ if (advanceModeSpec !== null) {
+ return advanceModeSpec;
+ }
+
+ const specBuilder = new BarChart();
+ specBuilder.setAxisDirection(lodexDirectionToIdDirection(direction));
+ specBuilder.setOrderBy(lodexOrderToIdOrder(params.orderBy));
+ specBuilder.setScale(lodexScaleToIdScale(scale));
+ specBuilder.setColor(colors);
+ specBuilder.setRoundValue(axisRoundValue);
+ specBuilder.setTooltip(tooltip);
+ specBuilder.setTooltipCategory(tooltipCategory);
+ specBuilder.setTooltipValue(tooltipValue);
+ specBuilder.setLabels(labels);
+ specBuilder.setLabelOverlap(labelOverlap);
+ specBuilder.setSize(barSize);
+ if (diagonalCategoryAxis) {
+ specBuilder.setLabelAngle(AXIS_X, -45);
+ }
+ if (diagonalValueAxis) {
+ specBuilder.setLabelAngle(AXIS_Y, -45);
+ }
+
+ return JSON.stringify(specBuilder.buildSpec(null, null, true), null, 2);
+ }, [advanceMode, advanceModeSpec]);
+
+ useEffect(() => {
+ if (!advanceMode) {
+ return;
+ }
+ updateAdminArgs('advanceModeSpec', spec, props);
+ }, [advanceMode, advanceModeSpec]);
+
+ const toggleAdvanceMode = () => {
+ updateAdminArgs('advanceMode', !args.advanceMode, props);
};
- static defaultProps = {
- args: defaultArgs,
- showMaxSize: true,
- showMaxValue: true,
- showMinValue: true,
- showOrderBy: true,
+ const handleAdvanceModeSpec = event => {
+ updateAdminArgs('advanceModeSpec', event.target.value, props);
};
- constructor(props) {
- super(props);
- this.setColors = this.setColors.bind(this);
- this.setTooltipValue = this.setTooltipValue.bind(this);
- this.setTooltipCategory = this.setTooltipCategory.bind(this);
- this.state = {
- colors: this.props.args.colors || defaultArgs.colors,
- };
- }
+ const clearAdvanceModeSpec = () => {
+ updateAdminArgs('advanceModeSpec', null, props);
+ };
- setParams = params => updateAdminArgs('params', params, this.props);
+ const handleParams = params => {
+ updateAdminArgs('params', params, props);
+ };
- setColors(colors) {
+ const handleColors = colors => {
updateAdminArgs('colors', colors || defaultArgs.colors, this.props);
- }
+ };
- setAxisRoundValue = () => {
- updateAdminArgs(
- 'axisRoundValue',
- !this.props.args.axisRoundValue,
- this.props,
- );
+ const handleAxisRoundValue = () => {
+ updateAdminArgs('axisRoundValue', !args.axisRoundValue, props);
};
- setScale = e => {
- updateAdminArgs('scale', e.target.value, this.props);
+ const handleScale = event => {
+ updateAdminArgs('scale', event.target.value, props);
};
- setDirection = e => {
- updateAdminArgs('direction', e.target.value, this.props);
+ const handleDirection = event => {
+ updateAdminArgs('direction', event.target.value, props);
};
- toggleDiagonalValueAxis = () => {
- updateAdminArgs(
- 'diagonalValueAxis',
- !this.props.args.diagonalValueAxis,
- this.props,
- );
+ const toggleDiagonalValueAxis = () => {
+ updateAdminArgs('diagonalValueAxis', !args.diagonalValueAxis, props);
};
- toggleDiagonalCategoryAxis = () => {
+ const toggleDiagonalCategoryAxis = () => {
updateAdminArgs(
'diagonalCategoryAxis',
- !this.props.args.diagonalCategoryAxis,
- this.props,
+ !args.diagonalCategoryAxis,
+ props,
);
};
- setBarSize = e => {
- updateAdminArgs('barSize', e.target.value, this.props);
+ const handleBarSize = event => {
+ updateAdminArgs('barSize', event.target, props);
};
- toggleTooltip = () => {
- updateAdminArgs('tooltip', !this.props.args.tooltip, this.props);
+ const toggleTooltip = () => {
+ updateAdminArgs('tooltip', args.tooltip, props);
};
- toggleLabels = () => {
- updateAdminArgs('labels', !this.props.args.labels, this.props);
+ const toggleLabels = () => {
+ updateAdminArgs('labels', args.labels, props);
};
- toggleLabelOverlap = () => {
- updateAdminArgs(
- 'labelOverlap',
- !this.props.args.labelOverlap,
- this.props,
- );
+ const toggleLabelOverlap = () => {
+ updateAdminArgs('labelOverlap', !args.labelOverlap, props);
};
- setTooltipCategory(tooltipCategory) {
- updateAdminArgs('tooltipCategory', tooltipCategory, this.props);
- }
-
- setTooltipValue(tooltipValue) {
- updateAdminArgs('tooltipValue', tooltipValue, this.props);
- }
+ const handleTooltipCategory = category => {
+ updateAdminArgs('tooltipCategory', category, props);
+ };
- render() {
- const {
- p: polyglot,
- args: {
- params,
- axisRoundValue,
- diagonalValueAxis,
- diagonalCategoryAxis,
- scale,
- direction,
- barSize,
- tooltip,
- tooltipCategory,
- tooltipValue,
- labels,
- labelOverlap,
- },
- showMaxSize,
- showMaxValue,
- showMinValue,
- showOrderBy,
- } = this.props;
+ const handleTooltipValue = value => {
+ updateAdminArgs('tooltipValue', value, props);
+ };
- return (
-
-
-
-
-
-
-
-
-
- }
- label={polyglot.t('diagonal_category_axis')}
- />
-
- }
- label={polyglot.t('diagonal_value_axis')}
- />
-
- }
- label={polyglot.t('axis_round_value')}
- />
+ return (
+
+
}
- label={polyglot.t('toggle_labels')}
+ label={polyglot.t('advancedMode')}
/>
-
- }
- label={polyglot.t('toggle_label_overlap')}
- />
-
-
-
-
-
-
- );
- }
-}
+
+
+ {!advanceMode ? (
+ <>
+
+
+
+
+
+
+
+ }
+ label={polyglot.t('diagonal_category_axis')}
+ />
+
+ }
+ label={polyglot.t('diagonal_value_axis')}
+ />
+
+ }
+ label={polyglot.t('axis_round_value')}
+ />
+
+ }
+ label={polyglot.t('toggle_labels')}
+ />
+
+ }
+ label={polyglot.t('toggle_label_overlap')}
+ />
+
+
+
+
+
+ >
+ ) : (
+ <>
+
+
+ >
+ )}
+
+ );
+};
+
+BarChartAdmin.defaultProps = {
+ args: defaultArgs,
+ showMaxSize: true,
+ showMaxValue: true,
+ showMinValue: true,
+ showOrderBy: true,
+};
+
+BarChartAdmin.propTypes = {
+ args: PropTypes.shape({
+ params: PropTypes.shape({
+ maxSize: PropTypes.number,
+ maxValue: PropTypes.number,
+ minValue: PropTypes.number,
+ orderBy: PropTypes.string,
+ }),
+ advanceMode: PropTypes.bool,
+ advanceModeSpec: PropTypes.string,
+ colors: PropTypes.string,
+ axisRoundValue: PropTypes.bool,
+ diagonalCategoryAxis: PropTypes.bool,
+ diagonalValueAxis: PropTypes.bool,
+ scale: PropTypes.oneOf(['log', 'linear']),
+ direction: PropTypes.oneOf(['horizontal', 'vertical']),
+ barSize: PropTypes.number,
+ tooltip: PropTypes.bool,
+ tooltipCategory: PropTypes.string,
+ tooltipValue: PropTypes.string,
+ labels: PropTypes.bool,
+ labelOverlap: PropTypes.bool,
+ }),
+ onChange: PropTypes.func.isRequired,
+ p: polyglotPropTypes.isRequired,
+ showMaxSize: PropTypes.bool.isRequired,
+ showMaxValue: PropTypes.bool.isRequired,
+ showMinValue: PropTypes.bool.isRequired,
+ showOrderBy: PropTypes.bool.isRequired,
+};
export default translate(BarChartAdmin);
diff --git a/src/app/js/formats/vega-lite/component/bar-chart/BarChartView.js b/src/app/js/formats/vega-lite/component/bar-chart/BarChartView.js
index ca195e6cf..f2bf72e16 100644
--- a/src/app/js/formats/vega-lite/component/bar-chart/BarChartView.js
+++ b/src/app/js/formats/vega-lite/component/bar-chart/BarChartView.js
@@ -17,6 +17,8 @@ import {
import BarChart from '../../models/BarChart';
import { CustomActionVegaLite } from '../vega-lite-component';
import deepClone from 'lodash.clonedeep';
+import InvalidFormat from '../../../InvalidFormat';
+import { VEGA_ACTIONS_WIDTH } from '../vega-lite-component/VegaLiteComponent';
const styles = {
container: {
@@ -27,6 +29,7 @@ const styles = {
class BarChartView extends Component {
render() {
const data = this.props.data;
+ const { advanceMode, advanceModeSpec, field } = this.props;
// Create a new bar chart instance
@@ -56,16 +59,27 @@ class BarChartView extends Component {
if (this.props.diagonalValueAxis)
barChartSpec.setLabelAngle(AXIS_Y, -45);
+ let advanceSpec;
+
+ try {
+ advanceSpec = JSON.parse(advanceModeSpec);
+ } catch (e) {
+ return ;
+ }
+
// return the finish chart
return (
{/* Make the chart responsive */}
{({ width }) => {
- const spec = barChartSpec.buildSpec(
- width,
- data.values.length,
- );
+ const spec = advanceMode
+ ? {
+ ...advanceSpec,
+ width: width - VEGA_ACTIONS_WIDTH,
+ }
+ : barChartSpec.buildSpec(width, data.values.length);
+ console.log(spec, advanceSpec);
return (
= width) {
- encoding.size = {
- value: width / (dataNumber + 1),
- };
+ if (!editMode) {
+ if (this.direction === AXIS_VERTICAL) {
+ width = widthIn - VEGA_ACTIONS_WIDTH;
+ height = 300;
+ if (dataNumber * (parseInt(this.size) + 4) >= width) {
+ encoding.size = {
+ value: width / (dataNumber + 1),
+ };
+ } else {
+ encoding.size = {
+ value: parseInt(this.size),
+ };
+ }
} else {
- encoding.size = {
- value: parseInt(this.size),
- };
+ width = widthIn - VEGA_ACTIONS_WIDTH;
+ height = { step: parseInt(this.size) };
}
- } else {
- width = widthIn - VEGA_ACTIONS_WIDTH;
- height = { step: parseInt(this.size) };
}
if (!this.labels) {
- return {
+ const toReturn = {
mark: model.mark,
encoding: encoding,
padding: this.padding,
- width: width,
- height: height,
autosize: this.autosize,
};
+
+ if (editMode) {
+ return toReturn;
+ }
+ return {
+ ...toReturn,
+ width,
+ height,
+ };
} else {
const mark = labelsModel.mark;
if (this.direction !== AXIS_VERTICAL) {
@@ -290,7 +301,7 @@ class BarChart extends BasicChart {
mark.align = 'center';
}
- return {
+ const toReturn = {
layer: [
{
mark: model.mark,
@@ -305,10 +316,18 @@ class BarChart extends BasicChart {
config: {
view: { strokeWidth: 0 },
},
- width: width,
- height: height,
autosize: this.autosize,
};
+
+ if (editMode) {
+ return toReturn;
+ }
+
+ return {
+ ...toReturn,
+ width,
+ height,
+ };
}
}
}
From 29efdd959a836a185345a097e3ba685554c8568a Mon Sep 17 00:00:00 2001
From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com>
Date: Fri, 15 Sep 2023 07:49:29 +0200
Subject: [PATCH 02/37] refactor: rename variable and tweak some code
---
.../component/bar-chart/BarChartAdmin.js | 52 +++++++++----------
.../component/bar-chart/BarChartView.js | 11 ++--
.../js/formats/vega-lite/models/BarChart.js | 11 ++--
.../js/formats/vega-lite/models/BasicChart.js | 5 ++
4 files changed, 41 insertions(+), 38 deletions(-)
diff --git a/src/app/js/formats/vega-lite/component/bar-chart/BarChartAdmin.js b/src/app/js/formats/vega-lite/component/bar-chart/BarChartAdmin.js
index a4d566585..1ef451986 100644
--- a/src/app/js/formats/vega-lite/component/bar-chart/BarChartAdmin.js
+++ b/src/app/js/formats/vega-lite/component/bar-chart/BarChartAdmin.js
@@ -32,8 +32,8 @@ export const defaultArgs = {
maxSize: 200,
orderBy: 'value/asc',
},
- advanceMode: false,
- advanceModeSpec: null,
+ advancedMode: false,
+ advancedModeSpec: null,
colors: MULTICHROMATIC_DEFAULT_COLORSET,
axisRoundValue: true,
diagonalCategoryAxis: false,
@@ -58,8 +58,8 @@ const BarChartAdmin = props => {
showOrderBy,
} = props;
const {
- advanceMode,
- advanceModeSpec,
+ advancedMode,
+ advancedModeSpec,
params,
tooltip,
tooltipCategory,
@@ -79,12 +79,12 @@ const BarChartAdmin = props => {
}, [args.colors]);
const spec = useMemo(() => {
- if (!advanceMode) {
+ if (!advancedMode) {
return null;
}
- if (advanceModeSpec !== null) {
- return advanceModeSpec;
+ if (advancedModeSpec !== null) {
+ return advancedModeSpec;
}
const specBuilder = new BarChart();
@@ -105,27 +105,27 @@ const BarChartAdmin = props => {
if (diagonalValueAxis) {
specBuilder.setLabelAngle(AXIS_Y, -45);
}
-
- return JSON.stringify(specBuilder.buildSpec(null, null, true), null, 2);
- }, [advanceMode, advanceModeSpec]);
+ specBuilder.setEditMode(true);
+ return JSON.stringify(specBuilder.buildSpec(), null, 2);
+ }, [advancedMode, advancedModeSpec]);
useEffect(() => {
- if (!advanceMode) {
+ if (!advancedMode) {
return;
}
- updateAdminArgs('advanceModeSpec', spec, props);
- }, [advanceMode, advanceModeSpec]);
+ updateAdminArgs('advancedModeSpec', spec, props);
+ }, [advancedMode, advancedModeSpec]);
- const toggleAdvanceMode = () => {
- updateAdminArgs('advanceMode', !args.advanceMode, props);
+ const toggleAdvancedMode = () => {
+ updateAdminArgs('advancedMode', !args.advancedMode, props);
};
- const handleAdvanceModeSpec = event => {
- updateAdminArgs('advanceModeSpec', event.target.value, props);
+ const handleAdvancedModeSpec = event => {
+ updateAdminArgs('advancedModeSpec', event.target.value, props);
};
- const clearAdvanceModeSpec = () => {
- updateAdminArgs('advanceModeSpec', null, props);
+ const clearAdvancedModeSpec = () => {
+ updateAdminArgs('advancedModeSpec', null, props);
};
const handleParams = params => {
@@ -195,8 +195,8 @@ const BarChartAdmin = props => {
}
label={polyglot.t('advancedMode')}
@@ -211,7 +211,7 @@ const BarChartAdmin = props => {
showMinValue={showMinValue}
showOrderBy={showOrderBy}
/>
- {!advanceMode ? (
+ {!advancedMode ? (
<>
{
>
) : (
<>
-