This is an automated email from the ASF dual-hosted git repository. maximebeauchemin pushed a commit to branch improve-matrixify in repository https://gitbox.apache.org/repos/asf/superset.git
commit d3bf6a20aa0e56ad768210a1b5ff10146af18ae6 Author: Maxime Beauchemin <maximebeauche...@gmail.com> AuthorDate: Tue Sep 9 00:51:01 2025 -0700 feat(matrixify): replace single toggle with separate horizontal/vertical layout controls Replace the single "Enable Matrixify" checkbox with two separate controls for better clarity: - "Enable vertical layout (rows)" - for creating matrix rows - "Enable horizontal layout (columns)" - for creating matrix columns This provides clearer user guidance about what each layout type does and allows independent control of row vs column matrix layouts. Key changes: - Split matrixify_enabled into matrixify_enable_vertical_layout and matrixify_enable_horizontal_layout - Updated all references across components to use new layout controls - Improved control panel organization with progressive disclosure - Enhanced visibility logic to show relevant controls based on layout selection - Added utility functions for checking layout states - Removed problematic validators that were blocking form rendering - Enabled MATRIXIFY feature flag for testing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <nore...@anthropic.com> --- superset-frontend/package-lock.json | 5 +- .../src/sections/matrixify.tsx | 44 +++++++++----- .../src/shared-controls/matrixifyControls.tsx | 70 +++++++++++++++------- .../superset-ui-core/src/chart/types/matrixify.ts | 20 +++++-- .../Chart/ChartContextMenu/ChartContextMenu.tsx | 5 +- .../src/components/Chart/ChartRenderer.jsx | 5 +- .../components/Chart/DrillBy/DrillByMenuItems.tsx | 5 +- .../explore/components/ExploreChartPanel/index.tsx | 8 ++- .../src/explore/controlPanels/sections.tsx | 47 ++++++++------- .../explore/controlUtils/getSectionsToRender.ts | 2 +- superset-frontend/src/utils/matrixifyUtils.ts | 56 +++++++++++++++++ superset/config.py | 2 +- 12 files changed, 201 insertions(+), 68 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index d2f9ca5b31..d4c0646fbb 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -60642,7 +60642,7 @@ }, "packages/superset-core": { "name": "@apache-superset/core", - "version": "0.0.1-rc2", + "version": "0.0.1-rc3", "license": "ISC", "devDependencies": { "@babel/cli": "^7.26.4", @@ -60652,7 +60652,8 @@ "@babel/preset-typescript": "^7.26.0", "@types/react": "^17.0.83", "install": "^0.13.0", - "npm": "^11.1.0" + "npm": "^11.1.0", + "typescript": "^5.0.0" }, "peerDependencies": { "antd": "^5.24.6", diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/sections/matrixify.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/sections/matrixify.tsx index 0054d5c136..f70df487fa 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/sections/matrixify.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/src/sections/matrixify.tsx @@ -20,20 +20,32 @@ import { t } from '@superset-ui/core'; import { ControlPanelSectionConfig } from '../types'; export const matrixifyEnableSection: ControlPanelSectionConfig = { - label: t('Enable matrixify'), + label: t('Matrixify'), expanded: true, controlSetRows: [ [ { - name: 'matrixify_enabled', + name: 'matrixify_enable_horizontal_layout', config: { type: 'CheckboxControl', - label: t('Enable matrixify'), - default: false, - renderTrigger: true, + label: t('Enable horizontal layout (columns)'), description: t( - 'Transform this chart into a matrix/grid of charts based on dimensions or metrics', + 'Create matrix columns by placing charts side-by-side', ), + default: false, + renderTrigger: true, + }, + }, + ], + [ + { + name: 'matrixify_enable_vertical_layout', + config: { + type: 'CheckboxControl', + label: t('Enable vertical layout (rows)'), + description: t('Create matrix rows by stacking charts vertically'), + default: false, + renderTrigger: true, }, }, ], @@ -42,9 +54,11 @@ export const matrixifyEnableSection: ControlPanelSectionConfig = { }; export const matrixifySection: ControlPanelSectionConfig = { - label: t('Matrixify'), + label: t('Cell layout & styling'), expanded: false, - visibility: ({ controls }) => controls?.matrixify_enabled?.value === true, + visibility: ({ controls }) => + controls?.matrixify_enable_vertical_layout?.value === true || + controls?.matrixify_enable_horizontal_layout?.value === true, controlSetRows: [ [ { @@ -105,9 +119,10 @@ export const matrixifySection: ControlPanelSectionConfig = { }; export const matrixifyRowSection: ControlPanelSectionConfig = { - label: t('Vertical layout'), + label: t('Vertical layout (rows)'), expanded: false, - visibility: ({ controls }) => controls?.matrixify_enabled?.value === true, + visibility: ({ controls }) => + controls?.matrixify_enable_vertical_layout?.value === true, controlSetRows: [ ['matrixify_show_row_labels'], ['matrixify_mode_rows'], @@ -118,13 +133,14 @@ export const matrixifyRowSection: ControlPanelSectionConfig = { ['matrixify_topn_metric_rows'], ['matrixify_topn_order_rows'], ], - tabOverride: 'data', + tabOverride: 'matrixify', }; export const matrixifyColumnSection: ControlPanelSectionConfig = { - label: t('Horizontal layout'), + label: t('Horizontal layout (columns)'), expanded: false, - visibility: ({ controls }) => controls?.matrixify_enabled?.value === true, + visibility: ({ controls }) => + controls?.matrixify_enable_horizontal_layout?.value === true, controlSetRows: [ ['matrixify_show_column_headers'], ['matrixify_mode_columns'], @@ -135,5 +151,5 @@ export const matrixifyColumnSection: ControlPanelSectionConfig = { ['matrixify_topn_metric_columns'], ['matrixify_topn_order_columns'], ], - tabOverride: 'data', + tabOverride: 'matrixify', }; diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/matrixifyControls.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/matrixifyControls.tsx index fcc473b587..f0ae52fd49 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/matrixifyControls.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/matrixifyControls.tsx @@ -43,16 +43,22 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {}; ['dimensions', t('Dimension members')], ], renderTrigger: true, + visibility: ({ controls }) => + controls?.[ + `matrixify_enable_${axis === 'rows' ? 'vertical' : 'horizontal'}_layout` + ]?.value === true, }; matrixifyControls[`matrixify_${axis}`] = { ...dndAdhocMetricControl, label: t(`Metrics`), multi: true, - validators: [], // Not required - // description: t(`Select metrics for ${axis}`), + validators: [], // No validation for metrics renderTrigger: true, visibility: ({ controls }) => + controls?.[ + `matrixify_enable_${axis === 'rows' ? 'vertical' : 'horizontal'}_layout` + ]?.value === true && controls?.[`matrixify_mode_${axis}`]?.value === 'metrics', }; @@ -62,7 +68,7 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {}; label: t(`Dimension selection`), description: t(`Select dimension and values`), default: { dimension: '', values: [] }, - validators: [], // Not required + validators: [], // No validation - rely on visibility renderTrigger: true, shouldMapStateToProps: (prevState, state) => { // Recalculate when any relevant form_data field changes @@ -82,12 +88,14 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {}; const getValue = (key: string, defaultValue?: any) => form_data?.[key] ?? controls?.[key]?.value ?? defaultValue; + const selectionMode = getValue( + `matrixify_dimension_selection_mode_${axis}`, + 'members', + ); + return { datasource, - selectionMode: getValue( - `matrixify_dimension_selection_mode_${axis}`, - 'members', - ), + selectionMode, topNMetric: getValue(`matrixify_topn_metric_${axis}`), topNValue: getValue(`matrixify_topn_value_${axis}`), topNOrder: getValue(`matrixify_topn_order_${axis}`), @@ -95,6 +103,9 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {}; }; }, visibility: ({ controls }) => + controls?.[ + `matrixify_enable_${axis === 'rows' ? 'vertical' : 'horizontal'}_layout` + ]?.value === true && controls?.[`matrixify_mode_${axis}`]?.value === 'dimensions', }; @@ -128,6 +139,9 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {}; ], renderTrigger: true, visibility: ({ controls }) => + controls?.[ + `matrixify_enable_${axis === 'rows' ? 'vertical' : 'horizontal'}_layout` + ]?.value === true && controls?.[`matrixify_mode_${axis}`]?.value === 'dimensions', }; @@ -138,7 +152,11 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {}; description: t(`How many top values to select`), default: 10, isInt: true, + validators: [], // No validation - rely on visibility visibility: ({ controls }) => + controls?.[ + `matrixify_enable_${axis === 'rows' ? 'vertical' : 'horizontal'}_layout` + ]?.value === true && controls?.[`matrixify_mode_${axis}`]?.value === 'dimensions' && controls?.[`matrixify_dimension_selection_mode_${axis}`]?.value === 'topn', @@ -148,9 +166,12 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {}; ...dndAdhocMetricControl, label: t(`Metric for ordering`), multi: false, - validators: [], // Not required + validators: [], // No validation - rely on visibility description: t(`Metric to use for ordering Top N values`), visibility: ({ controls }) => + controls?.[ + `matrixify_enable_${axis === 'rows' ? 'vertical' : 'horizontal'}_layout` + ]?.value === true && controls?.[`matrixify_mode_${axis}`]?.value === 'dimensions' && controls?.[`matrixify_dimension_selection_mode_${axis}`]?.value === 'topn', @@ -165,6 +186,9 @@ const matrixifyControls: Record<string, SharedControlConfig<any>> = {}; ['desc', t('Descending')], ], visibility: ({ controls }) => + controls?.[ + `matrixify_enable_${axis === 'rows' ? 'vertical' : 'horizontal'}_layout` + ]?.value === true && controls?.[`matrixify_mode_${axis}`]?.value === 'dimensions' && controls?.[`matrixify_dimension_selection_mode_${axis}`]?.value === 'topn', @@ -213,13 +237,21 @@ matrixifyControls.matrixify_charts_per_row = { !controls?.matrixify_fit_columns_dynamically?.value, }; -// Main enable control -matrixifyControls.matrixify_enabled = { +// Remove matrixify_enabled - use layout enables directly + +// Progressive disclosure controls for layout sections +matrixifyControls.matrixify_enable_vertical_layout = { type: 'CheckboxControl', - label: t('Enable matrixify'), - description: t( - 'Transform this chart into a matrix/grid of charts based on dimensions or metrics', - ), + label: t('Enable vertical layout (rows)'), + description: t('Create matrix rows by stacking charts vertically'), + default: false, + renderTrigger: true, +}; + +matrixifyControls.matrixify_enable_horizontal_layout = { + type: 'CheckboxControl', + label: t('Enable horizontal layout (columns)'), + description: t('Create matrix columns by placing charts side-by-side'), default: false, renderTrigger: true, }; @@ -234,8 +266,8 @@ matrixifyControls.matrixify_cell_title_template = { default: '', renderTrigger: true, visibility: ({ controls }) => - (controls?.matrixify_mode_rows?.value || - controls?.matrixify_mode_columns?.value) !== undefined, + controls?.matrixify_enable_vertical_layout?.value === true || + controls?.matrixify_enable_horizontal_layout?.value === true, }; // Matrix display controls @@ -246,8 +278,7 @@ matrixifyControls.matrixify_show_row_labels = { default: true, renderTrigger: true, visibility: ({ controls }) => - (controls?.matrixify_mode_rows?.value || - controls?.matrixify_mode_columns?.value) !== undefined, + controls?.matrixify_enable_vertical_layout?.value === true, }; matrixifyControls.matrixify_show_column_headers = { @@ -257,8 +288,7 @@ matrixifyControls.matrixify_show_column_headers = { default: true, renderTrigger: true, visibility: ({ controls }) => - (controls?.matrixify_mode_rows?.value || - controls?.matrixify_mode_columns?.value) !== undefined, + controls?.matrixify_enable_horizontal_layout?.value === true, }; export { matrixifyControls }; diff --git a/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.ts b/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.ts index b3e8f8397b..b72f801969 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.ts +++ b/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.ts @@ -96,9 +96,13 @@ export interface MatrixifyAxisConfig { * Complete Matrixify configuration in form data */ export interface MatrixifyFormData { - // Enable/disable matrixify functionality + // Enable/disable matrixify functionality (legacy) matrixify_enabled?: boolean; + // New layout enable controls + matrixify_enable_vertical_layout?: boolean; + matrixify_enable_horizontal_layout?: boolean; + // Row axis configuration matrixify_mode_rows?: MatrixifyMode; matrixify_rows?: AdhocMetric[]; @@ -177,8 +181,12 @@ export function getMatrixifyConfig( * Check if Matrixify is enabled and properly configured */ export function isMatrixifyEnabled(formData: MatrixifyFormData): boolean { - // First check if matrixify is explicitly enabled via checkbox - if (!formData.matrixify_enabled) { + // Check if either vertical or horizontal layout is enabled + const hasVerticalLayout = formData.matrixify_enable_vertical_layout === true; + const hasHorizontalLayout = + formData.matrixify_enable_horizontal_layout === true; + + if (!hasVerticalLayout && !hasHorizontalLayout) { return false; } @@ -216,7 +224,11 @@ export function getMatrixifyValidationErrors( const errors: string[] = []; // Only validate if matrixify is enabled - if (!formData.matrixify_enabled) { + const hasVerticalLayout = formData.matrixify_enable_vertical_layout === true; + const hasHorizontalLayout = + formData.matrixify_enable_horizontal_layout === true; + + if (!hasVerticalLayout && !hasHorizontalLayout) { return errors; } diff --git a/superset-frontend/src/components/Chart/ChartContextMenu/ChartContextMenu.tsx b/superset-frontend/src/components/Chart/ChartContextMenu/ChartContextMenu.tsx index 457636c109..98e7fb8a89 100644 --- a/superset-frontend/src/components/Chart/ChartContextMenu/ChartContextMenu.tsx +++ b/superset-frontend/src/components/Chart/ChartContextMenu/ChartContextMenu.tsx @@ -188,7 +188,10 @@ const ChartContextMenu = ( isFeatureEnabled(FeatureFlag.DrillBy) && canDrillBy && isDisplayed(ContextMenuItem.DrillBy) && - !formData.matrixify_enabled; // Disable drill by when matrixify is enabled + !( + formData.matrixify_enable_vertical_layout === true || + formData.matrixify_enable_horizontal_layout === true + ); // Disable drill by when matrixify is enabled const datasetResource = useDatasetDrillInfo( formData.datasource, diff --git a/superset-frontend/src/components/Chart/ChartRenderer.jsx b/superset-frontend/src/components/Chart/ChartRenderer.jsx index d10d7b0439..410a588813 100644 --- a/superset-frontend/src/components/Chart/ChartRenderer.jsx +++ b/superset-frontend/src/components/Chart/ChartRenderer.jsx @@ -153,7 +153,10 @@ class ChartRenderer extends Component { // Check if any matrixify-related properties have changed const hasMatrixifyChanges = () => { - if (!nextProps.formData.matrixify_enabled) return false; + const isMatrixifyEnabled = + nextProps.formData.matrixify_enable_vertical_layout === true || + nextProps.formData.matrixify_enable_horizontal_layout === true; + if (!isMatrixifyEnabled) return false; // Check all matrixify-related properties const matrixifyKeys = Object.keys(nextProps.formData).filter(key => diff --git a/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx b/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx index 3ac4a6dd8f..85b6af61ec 100644 --- a/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx +++ b/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx @@ -201,7 +201,10 @@ export const DrillByMenuItems = ({ }; // Don't render drill by menu items when matrixify is enabled - if (formData.matrixify_enabled) { + if ( + formData.matrixify_enable_vertical_layout === true || + formData.matrixify_enable_horizontal_layout === true + ) { return null; } diff --git a/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx b/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx index a01d797420..b1710f1a2b 100644 --- a/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx +++ b/superset-frontend/src/explore/components/ExploreChartPanel/index.tsx @@ -395,7 +395,10 @@ const ExploreChartPanel = ({ queriesResponse: chart.queriesResponse, })} {...(chart.chartStatus && { chartStatus: chart.chartStatus })} - hideRowCount={formData?.matrixify_enabled === true} + hideRowCount={ + formData?.matrixify_enable_vertical_layout === true || + formData?.matrixify_enable_horizontal_layout === true + } /> </ChartHeaderExtension> {renderChart()} @@ -412,7 +415,8 @@ const ExploreChartPanel = ({ chart.chartUpdateEndTime, refreshCachedQuery, formData?.row_limit, - formData?.matrixify_enabled, + formData?.matrixify_enable_vertical_layout, + formData?.matrixify_enable_horizontal_layout, renderChart, ], ); diff --git a/superset-frontend/src/explore/controlPanels/sections.tsx b/superset-frontend/src/explore/controlPanels/sections.tsx index 737ad1ad07..ef86feb487 100644 --- a/superset-frontend/src/explore/controlPanels/sections.tsx +++ b/superset-frontend/src/explore/controlPanels/sections.tsx @@ -288,26 +288,30 @@ function buildMatrixifySection( [`matrixify_topn_order_${axis}`], ]; + // Add enable checkbox at the beginning of each section + const enableControl = + axis === 'rows' + ? 'matrixify_enable_vertical_layout' + : 'matrixify_enable_horizontal_layout'; + + baseControls.unshift([enableControl]); + // Add specific controls for each axis if (axis === 'rows') { - // Add show row labels at the beginning - baseControls.unshift(['matrixify_show_row_labels']); - // Add row height control after show labels - baseControls.splice(1, 0, ['matrixify_row_height']); + // Add show row labels after enable + baseControls.splice(1, 0, ['matrixify_show_row_labels']); } else if (axis === 'columns') { - // Add show column headers at the beginning - baseControls.unshift(['matrixify_show_column_headers']); - // Add fit columns control after show headers - baseControls.splice(1, 0, ['matrixify_fit_columns_dynamically']); - // Add charts per row after fit columns control - baseControls.splice(2, 0, ['matrixify_charts_per_row']); + // Add show column headers after enable + baseControls.splice(1, 0, ['matrixify_show_column_headers']); } return { - label: axis === 'columns' ? t('Horizontal layout') : t('Vertical layout'), + label: + axis === 'columns' + ? t('Horizontal layout (columns)') + : t('Vertical layout (rows)'), expanded: true, tabOverride: 'matrixify', - visibility: ({ controls }) => controls?.matrixify_enabled?.value === true, controlSetRows: baseControls, }; } @@ -315,17 +319,18 @@ function buildMatrixifySection( export const matrixifyRows = buildMatrixifySection('rows'); export const matrixifyColumns = buildMatrixifySection('columns'); -export const matrixifyEnableSection: ControlPanelSectionConfig = { - label: t('Enable Matrixify'), - expanded: true, - tabOverride: 'matrixify', - controlSetRows: [['matrixify_enabled']], -}; +// Removed - checkboxes now inside their respective sections export const matrixifyCells: ControlPanelSectionConfig = { - label: t('Cells'), + label: t('Cell layout & styling'), expanded: true, tabOverride: 'matrixify', - visibility: ({ controls }) => controls?.matrixify_enabled?.value === true, - controlSetRows: [['matrixify_cell_title_template']], + visibility: ({ controls }) => + controls?.matrixify_enable_vertical_layout?.value === true || + controls?.matrixify_enable_horizontal_layout?.value === true, + controlSetRows: [ + ['matrixify_row_height', 'matrixify_fit_columns_dynamically'], + ['matrixify_charts_per_row'], + ['matrixify_cell_title_template'], + ], }; diff --git a/superset-frontend/src/explore/controlUtils/getSectionsToRender.ts b/superset-frontend/src/explore/controlUtils/getSectionsToRender.ts index 6fee00ef0f..4185a63116 100644 --- a/superset-frontend/src/explore/controlUtils/getSectionsToRender.ts +++ b/superset-frontend/src/explore/controlUtils/getSectionsToRender.ts @@ -75,9 +75,9 @@ const getMemoizedSectionsToRender = memoizeOne( return [ datasourceAndVizType as ControlPanelSectionConfig, matrixifyEnableSection as ControlPanelSectionConfig, - matrixifyCells as ControlPanelSectionConfig, matrixifyColumns as ControlPanelSectionConfig, matrixifyRows as ControlPanelSectionConfig, + matrixifyCells as ControlPanelSectionConfig, ] .filter(Boolean) // Filter out null/undefined sections .concat(controlPanelSections.filter(isControlPanelSectionConfig)) diff --git a/superset-frontend/src/utils/matrixifyUtils.ts b/superset-frontend/src/utils/matrixifyUtils.ts new file mode 100644 index 0000000000..ff8c3e061a --- /dev/null +++ b/superset-frontend/src/utils/matrixifyUtils.ts @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Utility functions for Matrixify functionality + */ + +/** + * Checks if Matrixify is enabled based on the new layout controls + * @param formData - The form data object + * @returns true if either vertical or horizontal layout is enabled + */ +export function isMatrixifyEnabled(formData: Record<string, any>): boolean { + return !!( + formData?.matrixify_enable_vertical_layout === true || + formData?.matrixify_enable_horizontal_layout === true + ); +} + +/** + * Checks if vertical layout (rows) is enabled + * @param formData - The form data object + * @returns true if vertical layout is enabled + */ +export function isVerticalLayoutEnabled( + formData: Record<string, any>, +): boolean { + return formData?.matrixify_enable_vertical_layout === true; +} + +/** + * Checks if horizontal layout (columns) is enabled + * @param formData - The form data object + * @returns true if horizontal layout is enabled + */ +export function isHorizontalLayoutEnabled( + formData: Record<string, any>, +): boolean { + return formData?.matrixify_enable_horizontal_layout === true; +} diff --git a/superset/config.py b/superset/config.py index b41992fe1e..f34f912aaa 100644 --- a/superset/config.py +++ b/superset/config.py @@ -625,7 +625,7 @@ DEFAULT_FEATURE_FLAGS: dict[str, bool] = { # in addition to relative timeshifts (e.g., "1 day ago") "DATE_RANGE_TIMESHIFTS_ENABLED": False, # Enable Matrixify feature for matrix-style chart layouts - "MATRIXIFY": False, + "MATRIXIFY": True, } # ------------------------------