From 829b8bc9810b56f05f88590d8e73e2d4af16bedd Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Sun, 10 Aug 2025 03:47:44 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E5=9B=BE?= =?UTF-8?q?=E8=A1=A8=E5=A4=9A=E5=BA=8F=E5=88=97=E6=A8=A1=E5=BC=8F=E4=B8=8B?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E6=8D=AE=E8=A1=A8=E6=A0=BC=E5=88=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/runtime/CHANGELOG.md | 4 + .../control/chart/chart.controller.ts | 110 +++++++++++++----- .../control/i-api-chart.controller.ts | 2 +- packages/runtime/src/locale/en/index.ts | 4 + packages/runtime/src/locale/zh-CN/index.ts | 4 + 5 files changed, 96 insertions(+), 28 deletions(-) diff --git a/packages/runtime/CHANGELOG.md b/packages/runtime/CHANGELOG.md index 41146f385d..786ad8f045 100644 --- a/packages/runtime/CHANGELOG.md +++ b/packages/runtime/CHANGELOG.md @@ -13,6 +13,10 @@ - 新增甘特图滑块的链接线绘制,新增部件参数linkdatasourcetype(链接数据获取模式)、linkappdataentityname(链接数据集应用实体名称)、linkappdedatasetname(链接应用实体结果集名称)、linknodedataname(链接节点数据属性名称)、fromdataitemname(链接起始数据项属性名称)、todataitemname(链接结束数据项属性名称) - 新增树节点数据拖拽状态属性 +### Changed + +- 更新图表多序列模式下的数据表格列处理逻辑 + ### Fixed - 修复数值项代码表值转换报错 diff --git a/packages/runtime/src/controller/control/chart/chart.controller.ts b/packages/runtime/src/controller/control/chart/chart.controller.ts index d354964c4f..22a44eb4e5 100644 --- a/packages/runtime/src/controller/control/chart/chart.controller.ts +++ b/packages/runtime/src/controller/control/chart/chart.controller.ts @@ -287,35 +287,26 @@ export class ChartController const serie = this.generator.seriesGenerators[0]; // 单序列,构建表格数据,第一列为分组属性,第二列为值属性的值,第三列为百分比 const { catalogField, valueField, groupData } = serie; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const fields = (serie as any).chartGenerator.entity.appDEFields; - // 获取到分类和值属性的title,构建表头 - const cataTitle = fields.find((field: IData) => { - return field.id === catalogField; - }); - const valueTitle = fields.find((field: IData) => { - return field.id === valueField; - }); const tempGridHeader = [ { id: catalogField, - name: cataTitle?.logicName, + name: ibiz.i18n.t('runtime.controller.control.chart.catalogField'), }, { id: valueField, - name: valueTitle?.logicName, + name: ibiz.i18n.t('runtime.controller.control.chart.value'), }, { id: 'srfpercent', - name: '百分比', + name: ibiz.i18n.t('runtime.controller.control.chart.percent'), }, ]; - this.state.gridHeaders = tempGridHeader; const tempData: IData[] = []; const total = this.computeTotal(valueField); if (groupData && groupData.$default_group) { + // 普通单序列 const group = groupData.$default_group; for (const [key, value] of group) { const tempValue = Number.isNaN(Number(value.value)) @@ -334,7 +325,35 @@ export class ChartController }; tempData.push(tempItem); } + } else if (groupData) { + tempGridHeader.unshift({ + id: 'srfSerieGroup', + name: ibiz.i18n.t('runtime.controller.control.chart.serieGroup'), + }); + // 根据名称模拟的多序列 + Object.keys(groupData).forEach((key: string) => { + const group = groupData[key]; + for (const [_key, value] of group) { + const tempValue = Number.isNaN(Number(value.value)) + ? 0 + : Number(value.value); + let percent: string = ''; + if (total === 0 || Number.isNaN(Number(value.value))) { + percent = '0%'; + } else { + percent = `${Math.round((tempValue / total) * 100)}%`; + } + const tempItem = { + srfSerieGroup: key, + [catalogField]: _key, + [valueField]: tempValue, + srfpercent: percent, + }; + tempData.push(tempItem); + } + }); } + this.state.gridHeaders = tempGridHeader; this.state.gridData = tempData; } @@ -351,31 +370,33 @@ export class ChartController // 多序列,表格第一列使用分组属性的值,后续其他列通过其他序列计算后动态组装, const tempHeaders: IData[] = []; const tempData: IData[] = []; - + tempHeaders.push({ + id: 'srfGroupName', + name: ibiz.i18n.t('runtime.controller.control.chart.serieGroup'), + }); this.generator.seriesGenerators.forEach((serie: IData) => { - const { catalogField, valueField, groupData } = serie; + const { catalogField, valueField, groupData, seriesName } = serie; + // eslint-disable-next-line @typescript-eslint/no-explicit-any - const fields = (serie as any).chartGenerator.entity.appDEFields; const _index = tempHeaders.findIndex((item: IData) => { return item.id === catalogField; }); if (_index < 0) { - const cataTitle = fields.find((field: IData) => { - return field.id === catalogField.toLowerCase(); - }); tempHeaders.push({ id: catalogField, - name: cataTitle?.logicName, + name: ibiz.i18n.t('runtime.controller.control.chart.catalogField'), }); } - const valueTitle = fields.find((field: IData) => { - return field.id === valueField.toLowerCase(); - }); - tempHeaders.push({ - id: valueField, - name: valueTitle?.logicName, + const temp = tempHeaders.find(item => { + return item.id === valueField; }); + if (!temp) { + tempHeaders.push({ + id: valueField, + name: ibiz.i18n.t('runtime.controller.control.chart.value'), + }); + } if (groupData && groupData.$default_group) { const group = groupData.$default_group; @@ -384,10 +405,13 @@ export class ChartController ? 0 : Number(value.value); const index = tempData.findIndex((item: IData) => { - return item[catalogField] === key; + return ( + item[catalogField] === key && item.srfGroupName === seriesName + ); }); if (index < 0) { const tempItem = { + srfGroupName: seriesName, [catalogField]: key, [valueField]: tempValue, }; @@ -403,6 +427,38 @@ export class ChartController this.state.gridData = tempData; } + public spanMethod(data: { + row: IData; + column: IData; + rowIndex: number; + columnIndex: number; + }): number[] { + const { row, column, rowIndex, columnIndex } = data; + if (column.property === 'srfGroupName') { + // 只有第一列或有值时才和并 + const allow = columnIndex === 0 || row.srfGroupName; + // 第二行开始合并 + if ( + rowIndex > 0 && + allow && + row.srfGroupName === this.state.gridData[rowIndex - 1]?.srfGroupName + ) { + return [0, 0]; + } + // 第一行计算出合并长度 + let rowspan = 1; + for (let i = rowIndex + 1; i < this.state.gridData.length; i++) { + if (allow && this.state.gridData[i].srfGroupName === row.srfGroupName) { + rowspan += 1; + } else { + break; + } + } + return [rowspan, 1]; + } + return [1, 1]; + } + /** * 计算表格数据 * diff --git a/packages/runtime/src/interface/api/controller/control/i-api-chart.controller.ts b/packages/runtime/src/interface/api/controller/control/i-api-chart.controller.ts index 4e404d83af..c7ebee1b30 100644 --- a/packages/runtime/src/interface/api/controller/control/i-api-chart.controller.ts +++ b/packages/runtime/src/interface/api/controller/control/i-api-chart.controller.ts @@ -9,7 +9,7 @@ import { IApiMDControlController } from './i-api-md-control.controller'; * @export * @interface IApiChartController * @extends {IApiMDControlController} - * @ctrlparams {name:chartid,title:图表标识,parameterType:string,description:用于指定图表标识} + * @ctrlparams {name:chartid,title:图表标识,parameterType:string,description:此部件参数仅应用于bi报表,用于指定图表标识} * @ctrlparams {name:enabledrilldetail,title:是否开启数据反查,defaultvalue:[],parameterType:IApiData[],description:此部件参数仅应用于bi报表。主要用于判断当前点击序列是否开启数据反查,如果当前序列有反查视图模型,则左键单击时弹出检查明细按钮} * @ctrlparams {"name":"mdctrlrefreshmode","title":"刷新模式","defaultvalue":"'cache'","parameterType":"'nocache' | 'cache'","description":"多数据部件刷新模式,当值为 'cache',部件刷新时保留选中数据;当值为 'nocache',部件刷新时清空选中数据","effectPlatform":"web"} * @ctrlparams {"name":"mode","title":"柱状图图表绘制模式","defaultvalue":"'DEFAULT'","parameterType":"'DEFAULT' | 'ROW'","description":"控制柱状图绘制方向,默认垂直绘制,为ROW时水平绘制"} diff --git a/packages/runtime/src/locale/en/index.ts b/packages/runtime/src/locale/en/index.ts index b0f7293b9d..dcdb454a1f 100644 --- a/packages/runtime/src/locale/en/index.ts +++ b/packages/runtime/src/locale/en/index.ts @@ -92,6 +92,10 @@ export const en = { classificationNotString: 'The configured classification attribute value is not an string', errorJson: 'JSON parsing error', + value: 'Value', + percent: 'Percent', + serieGroup: 'Serie group', + catalogField: 'Catalog field', }, dataView: { noBehaviourGroup: diff --git a/packages/runtime/src/locale/zh-CN/index.ts b/packages/runtime/src/locale/zh-CN/index.ts index 53add3eb74..e93b5f0c2f 100644 --- a/packages/runtime/src/locale/zh-CN/index.ts +++ b/packages/runtime/src/locale/zh-CN/index.ts @@ -79,6 +79,10 @@ export const zhCn = { classificationNotArray: '配置的分类属性值不是一个数组', classificationNotString: '配置的分类属性值不是一个字符串', errorJson: 'JSON解析错误', + value: '值', + percent: '百分比', + serieGroup: '分组', + catalogField: '分类', }, dataView: { noBehaviourGroup: '操作项没有配置界面行为组', -- Gitee From 0d537896a9d73742d0957adede9fb24e16c46d24 Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Sun, 10 Aug 2025 06:04:17 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=9B=A0=E4=B8=BA?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=AF=BC=E8=88=AA=E6=A0=8F=E9=87=8C=E7=9A=84?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=8F=E6=8F=90=E7=A4=BA=E5=88=86=E9=9A=94?= =?UTF-8?q?=E7=AC=A6=E5=AF=BC=E8=87=B4=E7=9A=84=E6=AD=BB=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/runtime/CHANGELOG.md | 1 + .../control/exp-bar/exp-bar.controller.ts | 32 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/runtime/CHANGELOG.md b/packages/runtime/CHANGELOG.md index 786ad8f045..eebbebfc56 100644 --- a/packages/runtime/CHANGELOG.md +++ b/packages/runtime/CHANGELOG.md @@ -19,6 +19,7 @@ ### Fixed +- 修复因为设置导航栏里的搜索栏提示分隔符导致的死循环问题 - 修复数值项代码表值转换报错 - 修复选择视图选中数据回显异常 diff --git a/packages/runtime/src/controller/control/exp-bar/exp-bar.controller.ts b/packages/runtime/src/controller/control/exp-bar/exp-bar.controller.ts index c6c4450432..8a1382bc9d 100644 --- a/packages/runtime/src/controller/control/exp-bar/exp-bar.controller.ts +++ b/packages/runtime/src/controller/control/exp-bar/exp-bar.controller.ts @@ -7,7 +7,12 @@ import { IDEDataView, INavigatable, } from '@ibiz/model-core'; -import { RuntimeError, RuntimeModelError } from '@ibiz-template/core'; +import { + IBizContext, + IBizParams, + RuntimeError, + RuntimeModelError, +} from '@ibiz-template/core'; import { IExpBarControlState, IExpBarControlEvent, @@ -23,6 +28,7 @@ import { calcDeCodeNameById } from '../../../model'; import { calcNavParams } from '../../../utils'; import { ControlController } from '../../common'; import { ControllerEvent, hasSubRoute } from '../../utils'; +import { CTX } from '../../ctx'; type XDataControlModel = IDEGrid | IDEList | IDEDataView; @@ -104,6 +110,30 @@ export class ExpBarControlController< */ navStack: IData[] = []; + constructor(model: T, context: IContext, params: IParams, ctx: CTX) { + super( + model, + IBizContext.create({}, context), + new IBizParams({}, params), + ctx, + ); + // 更新搜索栏的模型 + if (this.model.enableSearch) { + const modelData = this.view.model.viewLayoutPanel?.controls?.find( + item => item.id === 'searchbar', + ); + if (modelData && modelData.controlParam) { + const { SEARCHPHSEPARATOR } = this.model.controlParam?.ctrlParams || {}; + if (SEARCHPHSEPARATOR) { + modelData.controlParam.ctrlParams = { + ...(modelData.controlParam.ctrlParams || {}), + SEARCHPHSEPARATOR, + }; + } + } + } + } + protected initState(): void { super.initState(); this.state.query = ''; -- Gitee