diff --git a/.collaboration b/.collaboration index 09cb35c7..02fa47f7 100644 --- a/.collaboration +++ b/.collaboration @@ -2270,19 +2270,7 @@ }, { "ModuleName": "PCPage/工作台首页", - "State": 1, - "LockedBy": { - "UserName": "cuckooent", - "Email": "phoben@qq.com" - }, - "LockDateTime": "2024-11-05T15:41:14.1793883+08:00", - "ModuleType": 1, - "ToRemoveFiles": [ - "Pages\\工作台\\工作台首页.json", - "Pages\\工作台\\工作台首页.rd", - "Pages\\3868fc7f40b841649f14b5adba61954.json", - "Pages\\3868fc7f40b841649f14b5adba61954.rd" - ] + "ModuleType": 1 }, { "ModuleName": "PCPage/项目负荷 (2)", @@ -2482,45 +2470,15 @@ }, { "ModuleName": "RdlReport/人员工时报表", - "State": 1, - "LockedBy": { - "UserName": "cuckooent", - "Email": "phoben@qq.com" - }, - "LockDateTime": "2024-11-05T15:48:44.0898019+08:00", - "ModuleType": 18, - "ToRemoveFiles": [ - "Reports\\人员工时报表.json", - "Reports\\人员工时报表.rdlx" - ] + "ModuleType": 18 }, { "ModuleName": "RdlReport/客户工时报表", - "State": 1, - "LockedBy": { - "UserName": "cuckooent", - "Email": "phoben@qq.com" - }, - "LockDateTime": "2024-11-05T15:41:30.5558294+08:00", - "ModuleType": 18, - "ToRemoveFiles": [ - "Reports\\客户工时报表.json", - "Reports\\客户工时报表.rdlx" - ] + "ModuleType": 18 }, { "ModuleName": "RdlReport/项目工时报表", - "State": 1, - "LockedBy": { - "UserName": "cuckooent", - "Email": "phoben@qq.com" - }, - "LockDateTime": "2024-11-05T15:50:11.624925+08:00", - "ModuleType": 18, - "ToRemoveFiles": [ - "Reports\\项目工时报表.json", - "Reports\\项目工时报表.rdlx" - ] + "ModuleType": 18 }, { "ModuleName": "ServerCommand/复活流程", diff --git a/Pages/工作台/工作台首页.json b/Pages/工作台/工作台首页.json index 07e920b6..c1ece950 100644 --- a/Pages/工作台/工作台首页.json +++ b/Pages/工作台/工作台首页.json @@ -684,7 +684,7 @@ ], "JSONDataSources": [], "ImageDataSource": [], - "Config": "{\"option\":\"console.log(Context[\\\"recommands\\\"]);\\n\\n// 处理数据,生成节点和链接 \\nconst processData = (data) => {\\n // 生成颜色函数 - 使用HSL颜色空间 \\n const getColorByDepthAndIndex = (depth, index, totalInDepth) => {\\n // 黄金分割比 \\n const goldenRatio = 0.618033988749895;\\n\\n // 使用索引和黄金分割比来生成分散的色相值 \\n // 直接使用0-360的完整色相范围 \\n const hue = ((index * goldenRatio) % 1) * 360;\\n\\n // 统一的饱和度和明度 \\n return `hsl(${hue}, 60%, 55%)`;\\n };\\n\\n // 收集所有唯一的节点 \\n const typeSet = new Set(data.map(item => item.类型 || \\\"其他\\\"));\\n const projectSet = new Set(data.map(item => item.项目 || \\\"未知项目\\\"));\\n const taskSet = new Set(data.map(item => item.任务 || \\\"未知任务\\\"));\\n\\n // 转换为数组以便计算总数和索引 \\n const typeArray = Array.from(typeSet);\\n const projectArray = Array.from(projectSet);\\n const taskArray = Array.from(taskSet);\\n\\n // 预计算每个节点的总值 \\n const nodeValues = {};\\n\\n // 计算类型节点的值 \\n data.forEach(item => {\\n nodeValues[item.类型] = (nodeValues[item.类型] || 0) + item.数量;\\n nodeValues[item.项目] = (nodeValues[item.项目] || 0) + item.数量;\\n nodeValues[item.任务] = (nodeValues[item.任务] || 0) + item.数量;\\n });\\n\\n /// 生成节点数组,确保节点按照类型、项目、任务的顺序排列 \\n const nodes = [\\n // 类型节点 \\n ...typeArray.map((name, index) => ({\\n name: name,\\n depth: 0,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(0, index, typeArray.length),\\n borderColor: getColorByDepthAndIndex(0, index, typeArray.length)\\n }\\n })),\\n // 项目节点 \\n ...projectArray.map((name, index) => ({\\n name: name,\\n depth: 1,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(1, index, projectArray.length),\\n borderColor: getColorByDepthAndIndex(1, index, projectArray.length)\\n }\\n })),\\n // 任务节点 \\n ...taskArray.map((name, index) => ({\\n name: name,\\n depth: 2,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(2, index, taskArray.length),\\n borderColor: getColorByDepthAndIndex(2, index, taskArray.length)\\n }\\n }))\\n ];\\n\\n\\n // 生成连接数组 \\n const links = [];\\n\\n // 类型 -> 项目的链接 \\n data.forEach(item => {\\n const existingLink = links.find(\\n link => link.source === item.类型 && link.target === item.项目\\n );\\n if (existingLink) {\\n existingLink.value += item.数量;\\n } else {\\n links.push({\\n source: item.类型,\\n target: item.项目,\\n value: item.数量\\n });\\n }\\n });\\n\\n // 项目 -> 任务的链接 \\n data.forEach(item => {\\n const existingLink = links.find(\\n link => link.source === item.项目 && link.target === item.任务\\n );\\n if (existingLink) {\\n existingLink.value += item.数量;\\n } else {\\n links.push({\\n source: item.项目,\\n target: item.任务,\\n value: item.数量\\n });\\n }\\n });\\n\\n return { nodes, links };\\n};\\n\\n//获取提示文字\\nconst gettooltip = (params) => {\\n console.log(params);\\n if (params.dataType === 'node') {\\n return `${params.name}\\\\n数量: ${params.value}`;\\n }\\n return `${params.data.source} → ${params.data.target}\\\\n数量: ${params.value}`;\\n}\\n\\n// 处理数据 \\nconst { nodes, links } = processData(Context[\\\"recommands\\\"]);\\n\\n// Echarts配置 \\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"项目反馈桑基图\\\",\\n subtext:\\\"展示各个项目任务的不同反馈分类占比\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n tooltip: {\\n trigger: 'item',\\n triggerOn: 'mousemove',\\n formatter: gettooltip\\n },\\n series: [{\\n type: \\\"sankey\\\",\\n animation: true,\\n animationDuration: 300,\\n animationEasingUpdate: 'quinticInOut',\\n left: '5%',\\n top: '12%',\\n right: '20%',\\n bottom: '12%',\\n emphasis: {\\n focus: 'adjacency'\\n },\\n nodeAlign: 'left',\\n orient: 'horizontal',\\n data: nodes,\\n links: links,\\n nodeGap: 15,\\n nodeWidth: 25,\\n draggable: true,\\n lineStyle: {\\n color: 'source',\\n curveness: 0.5,\\n opacity: 0.6,\\n width: function (params) {\\n return Math.max(10, params.value);\\n }\\n },\\n label: {\\n position: 'right',\\n fontSize: 12,\\n lineHeight: 16,\\n color: '#000000',\\n distance: 10,\\n formatter: function (params) {\\n var name = params.name;\\n if (name.length > 10) {\\n name = name.substring(0, 10) + '...';\\n }\\n if (params.value && params.value > 0) {\\n return `${name}(${params.value}个)`;\\n }\\n return \\\"\\\";\\n },\\n show: true,\\n align: 'left',\\n verticalAlign: 'middle',\\n backgroundColor:'#ffffffa1',\\n overflow: 'break',\\n padding: [4, 8],\\n borderRadius: 4\\n }\\n }]\\n};\",\"graphTheme\":null,\"displayMode\":\"canvas\",\"jsCode\":\"\\n async ({Context,JSONContext,ImageContext,echarts,myChart,dat,Forguncy,d3,setInterval,setTimeout,ForguncyEchartsHelper,PublicResource})=>{\\n var datGUI=undefined;\\n var option={};\\n console.log(Context[\\\"recommands\\\"]);\\n// 处理数据,生成节点和链接 \\nconst processData = (data) => {\\n // 生成颜色函数 - 使用HSL颜色空间 \\n const getColorByDepthAndIndex = (depth, index, totalInDepth) => {\\n // 黄金分割比 \\n const goldenRatio = 0.618033988749895;\\n // 使用索引和黄金分割比来生成分散的色相值 \\n // 直接使用0-360的完整色相范围 \\n const hue = ((index * goldenRatio) % 1) * 360;\\n // 统一的饱和度和明度 \\n return `hsl(${hue}, 60%, 55%)`;\\n };\\n // 收集所有唯一的节点 \\n const typeSet = new Set(data.map(item => item.类型 || \\\"其他\\\"));\\n const projectSet = new Set(data.map(item => item.项目 || \\\"未知项目\\\"));\\n const taskSet = new Set(data.map(item => item.任务 || \\\"未知任务\\\"));\\n // 转换为数组以便计算总数和索引 \\n const typeArray = Array.from(typeSet);\\n const projectArray = Array.from(projectSet);\\n const taskArray = Array.from(taskSet);\\n // 预计算每个节点的总值 \\n const nodeValues = {};\\n // 计算类型节点的值 \\n data.forEach(item => {\\n nodeValues[item.类型] = (nodeValues[item.类型] || 0) + item.数量;\\n nodeValues[item.项目] = (nodeValues[item.项目] || 0) + item.数量;\\n nodeValues[item.任务] = (nodeValues[item.任务] || 0) + item.数量;\\n });\\n /// 生成节点数组,确保节点按照类型、项目、任务的顺序排列 \\n const nodes = [\\n // 类型节点 \\n ...typeArray.map((name, index) => ({\\n name: name,\\n depth: 0,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(0, index, typeArray.length),\\n borderColor: getColorByDepthAndIndex(0, index, typeArray.length)\\n }\\n })),\\n // 项目节点 \\n ...projectArray.map((name, index) => ({\\n name: name,\\n depth: 1,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(1, index, projectArray.length),\\n borderColor: getColorByDepthAndIndex(1, index, projectArray.length)\\n }\\n })),\\n // 任务节点 \\n ...taskArray.map((name, index) => ({\\n name: name,\\n depth: 2,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(2, index, taskArray.length),\\n borderColor: getColorByDepthAndIndex(2, index, taskArray.length)\\n }\\n }))\\n ];\\n // 生成连接数组 \\n const links = [];\\n // 类型 -> 项目的链接 \\n data.forEach(item => {\\n const existingLink = links.find(link => link.source === item.类型 && link.target === item.项目);\\n if (existingLink) {\\n existingLink.value += item.数量;\\n }\\n else {\\n links.push({\\n source: item.类型,\\n target: item.项目,\\n value: item.数量\\n });\\n }\\n });\\n // 项目 -> 任务的链接 \\n data.forEach(item => {\\n const existingLink = links.find(link => link.source === item.项目 && link.target === item.任务);\\n if (existingLink) {\\n existingLink.value += item.数量;\\n }\\n else {\\n links.push({\\n source: item.项目,\\n target: item.任务,\\n value: item.数量\\n });\\n }\\n });\\n return { nodes, links };\\n};\\n//获取提示文字\\nconst gettooltip = (params) => {\\n console.log(params);\\n if (params.dataType === 'node') {\\n return `${params.name}\\\\n数量: ${params.value}`;\\n }\\n return `${params.data.source} → ${params.data.target}\\\\n数量: ${params.value}`;\\n};\\n// 处理数据 \\nconst { nodes, links } = processData(Context[\\\"recommands\\\"]);\\n// Echarts配置 \\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"项目反馈桑基图\\\",\\n subtext: \\\"展示各个项目任务的不同反馈分类占比\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n tooltip: {\\n trigger: 'item',\\n triggerOn: 'mousemove',\\n formatter: gettooltip\\n },\\n series: [{\\n type: \\\"sankey\\\",\\n animation: true,\\n animationDuration: 300,\\n animationEasingUpdate: 'quinticInOut',\\n left: '5%',\\n top: '12%',\\n right: '20%',\\n bottom: '12%',\\n emphasis: {\\n focus: 'adjacency'\\n },\\n nodeAlign: 'left',\\n orient: 'horizontal',\\n data: nodes,\\n links: links,\\n nodeGap: 15,\\n nodeWidth: 25,\\n draggable: true,\\n lineStyle: {\\n color: 'source',\\n curveness: 0.5,\\n opacity: 0.6,\\n width: function (params) {\\n return Math.max(10, params.value);\\n }\\n },\\n label: {\\n position: 'right',\\n fontSize: 12,\\n lineHeight: 16,\\n color: '#000000',\\n distance: 10,\\n formatter: function (params) {\\n var name = params.name;\\n if (name.length > 10) {\\n name = name.substring(0, 10) + '...';\\n }\\n if (params.value && params.value > 0) {\\n return `${name}(${params.value}个)`;\\n }\\n return \\\"\\\";\\n },\\n show: true,\\n align: 'left',\\n verticalAlign: 'middle',\\n backgroundColor: '#ffffffa1',\\n overflow: 'break',\\n padding: [4, 8],\\n borderRadius: 4\\n }\\n }]\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}" + "Config": "{\"option\":\"console.log(Context[\\\"recommands\\\"]);\\n\\n// 处理数据,生成节点和链接 \\nconst processData = (data) => {\\n // 生成颜色函数 - 使用HSL颜色空间 \\n const getColorByDepthAndIndex = (depth, index, totalInDepth) => {\\n // 黄金分割比 \\n const goldenRatio = 0.618033988749895;\\n\\n // 使用索引和黄金分割比来生成分散的色相值 \\n // 直接使用0-360的完整色相范围 \\n const hue = ((index * goldenRatio) % 1) * 360;\\n\\n // 统一的饱和度和明度 \\n return `hsl(${hue}, 60%, 55%)`;\\n };\\n\\n // 收集所有唯一的节点 \\n const typeSet = new Set(data.map(item => item.类型 || \\\"其他\\\"));\\n const projectSet = new Set(data.map(item => item.项目 || \\\"未知项目\\\"));\\n const taskSet = new Set(data.map(item => item.任务 || \\\"未知任务\\\"));\\n\\n // 转换为数组以便计算总数和索引 \\n const typeArray = Array.from(typeSet);\\n const projectArray = Array.from(projectSet);\\n const taskArray = Array.from(taskSet);\\n\\n // 给每个一级节点(类型)分配一个固定颜色 \\n const typeColors = {};\\n typeArray.forEach((type, index) => {\\n const hue = ((index * 0.618033988749895) % 1) * 360;\\n typeColors[type] = `hsl(${hue}, 60%, 55%)`;\\n });\\n\\n // 创建项目到类型的映射,用于追踪源头 \\n const projectToTypeMap = {};\\n data.forEach(item => {\\n projectToTypeMap[item.项目] = item.类型;\\n });\\n\\n // 预计算每个节点的总值 \\n const nodeValues = {};\\n\\n // 计算类型节点的值 \\n data.forEach(item => {\\n nodeValues[item.类型] = (nodeValues[item.类型] || 0) + item.数量;\\n nodeValues[item.项目] = (nodeValues[item.项目] || 0) + item.数量;\\n nodeValues[item.任务] = (nodeValues[item.任务] || 0) + item.数量;\\n });\\n\\n /// 生成节点数组,确保节点按照类型、项目、任务的顺序排列 \\n const nodes = [\\n // 类型节点 \\n ...typeArray.map((name, index) => ({\\n name: name,\\n depth: 0,\\n value: nodeValues[name],\\n itemStyle: {\\n color: typeColors[name],\\n borderColor: typeColors[name]\\n }\\n })),\\n // 项目节点 \\n ...projectArray.map((name, index) => ({\\n name: name,\\n depth: 1,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(1, index, projectArray.length),\\n borderColor: getColorByDepthAndIndex(1, index, projectArray.length)\\n }\\n })),\\n // 任务节点 \\n ...taskArray.map((name, index) => ({\\n name: name,\\n depth: 2,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(2, index, taskArray.length),\\n borderColor: getColorByDepthAndIndex(2, index, taskArray.length)\\n }\\n }))\\n ];\\n\\n\\n // 生成连接数组 \\n const links = [];\\n\\n // 类型 -> 项目的链接 \\n data.forEach(item => {\\n const existingLink = links.find(\\n link => link.source === item.类型 && link.target === item.项目\\n );\\n if (existingLink) {\\n existingLink.value += item.数量;\\n } else {\\n links.push({\\n source: item.类型,\\n target: item.项目,\\n value: item.数量,\\n lineStyle: {\\n color: typeColors[item.类型],\\n opacity: 0.7\\n }\\n });\\n }\\n });\\n\\n // 项目 -> 任务的链接 \\n data.forEach(item => {\\n const existingLink = links.find(\\n link => link.source === item.项目 && link.target === item.任务\\n );\\n if (existingLink) {\\n existingLink.value += item.数量;\\n } else {\\n // 确保正确获取源头类型的颜色 \\n const sourceType = projectToTypeMap[item.项目];\\n if (!typeColors[sourceType]) {\\n console.warn(`找不到类型颜色: ${sourceType} for 项目: ${item.项目}`);\\n }\\n\\n links.push({\\n source: item.项目,\\n target: item.任务,\\n value: item.数量,\\n lineStyle: {\\n color: typeColors[sourceType] || '#999', // 添加后备颜色 \\n opacity: 0.7\\n },\\n // 添加源类型信息便于调试 \\n sourceType: sourceType\\n });\\n }\\n });\\n\\n return { nodes, links };\\n};\\n\\n//获取提示文字\\nconst gettooltip = (params) => {\\n console.log(params);\\n if (params.dataType === 'node') {\\n return `${params.name}\\\\n数量: ${params.value}`;\\n }\\n return `${params.data.source} → ${params.data.target}\\\\n数量: ${params.value}`;\\n}\\n\\n// 处理数据 \\nconst { nodes, links } = processData(Context[\\\"recommands\\\"]);\\n\\n// Echarts配置 \\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"项目反馈桑基图\\\",\\n subtext: \\\"展示各个项目任务的不同反馈分类占比\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n tooltip: {\\n trigger: 'item',\\n triggerOn: 'mousemove',\\n formatter: gettooltip\\n },\\n series: [{\\n type: \\\"sankey\\\",\\n animation: true,\\n animationDuration: 300,\\n animationEasingUpdate: 'quinticInOut',\\n left: '5%',\\n top: '12%',\\n right: '20%',\\n bottom: '12%',\\n nodeAlign: 'left',\\n orient: 'horizontal',\\n data: nodes,\\n links: links,\\n nodeGap: 15,\\n nodeWidth: 25,\\n draggable: true,\\n lineStyle: {\\n curveness: 0.5,\\n opacity: 0.7,\\n width: function (params) {\\n return Math.max(10, params.value);\\n },\\n shadowBlur: 3,\\n shadowColor: 'rgba(0,0,0,0.2)'\\n },\\n emphasis: {\\n focus: 'adjacency',\\n lineStyle: {\\n opacity: 0.9,\\n shadowBlur: 10,\\n shadowColor: 'rgba(0,0,0,0.5)'\\n }\\n },\\n label: {\\n position: 'right',\\n fontSize: 12,\\n lineHeight: 16,\\n color: '#000000',\\n distance: 10,\\n formatter: function (params) {\\n var name = params.name;\\n if (name.length > 10) {\\n name = name.substring(0, 10) + '...';\\n }\\n if (params.value && params.value > 0) {\\n return `${name}(${params.value}个)`;\\n }\\n return \\\"\\\";\\n },\\n show: true,\\n align: 'left',\\n verticalAlign: 'middle',\\n backgroundColor: '#ffffffa1',\\n overflow: 'break',\\n padding: [4, 8],\\n borderRadius: 4\\n }\\n }]\\n};\",\"graphTheme\":null,\"displayMode\":\"canvas\",\"jsCode\":\"\\n async ({Context,JSONContext,ImageContext,echarts,myChart,dat,Forguncy,d3,setInterval,setTimeout,ForguncyEchartsHelper,PublicResource})=>{\\n var datGUI=undefined;\\n var option={};\\n console.log(Context[\\\"recommands\\\"]);\\n// 处理数据,生成节点和链接 \\nconst processData = (data) => {\\n // 生成颜色函数 - 使用HSL颜色空间 \\n const getColorByDepthAndIndex = (depth, index, totalInDepth) => {\\n // 黄金分割比 \\n const goldenRatio = 0.618033988749895;\\n // 使用索引和黄金分割比来生成分散的色相值 \\n // 直接使用0-360的完整色相范围 \\n const hue = ((index * goldenRatio) % 1) * 360;\\n // 统一的饱和度和明度 \\n return `hsl(${hue}, 60%, 55%)`;\\n };\\n // 收集所有唯一的节点 \\n const typeSet = new Set(data.map(item => item.类型 || \\\"其他\\\"));\\n const projectSet = new Set(data.map(item => item.项目 || \\\"未知项目\\\"));\\n const taskSet = new Set(data.map(item => item.任务 || \\\"未知任务\\\"));\\n // 转换为数组以便计算总数和索引 \\n const typeArray = Array.from(typeSet);\\n const projectArray = Array.from(projectSet);\\n const taskArray = Array.from(taskSet);\\n // 给每个一级节点(类型)分配一个固定颜色 \\n const typeColors = {};\\n typeArray.forEach((type, index) => {\\n const hue = ((index * 0.618033988749895) % 1) * 360;\\n typeColors[type] = `hsl(${hue}, 60%, 55%)`;\\n });\\n // 创建项目到类型的映射,用于追踪源头 \\n const projectToTypeMap = {};\\n data.forEach(item => {\\n projectToTypeMap[item.项目] = item.类型;\\n });\\n // 预计算每个节点的总值 \\n const nodeValues = {};\\n // 计算类型节点的值 \\n data.forEach(item => {\\n nodeValues[item.类型] = (nodeValues[item.类型] || 0) + item.数量;\\n nodeValues[item.项目] = (nodeValues[item.项目] || 0) + item.数量;\\n nodeValues[item.任务] = (nodeValues[item.任务] || 0) + item.数量;\\n });\\n /// 生成节点数组,确保节点按照类型、项目、任务的顺序排列 \\n const nodes = [\\n // 类型节点 \\n ...typeArray.map((name, index) => ({\\n name: name,\\n depth: 0,\\n value: nodeValues[name],\\n itemStyle: {\\n color: typeColors[name],\\n borderColor: typeColors[name]\\n }\\n })),\\n // 项目节点 \\n ...projectArray.map((name, index) => ({\\n name: name,\\n depth: 1,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(1, index, projectArray.length),\\n borderColor: getColorByDepthAndIndex(1, index, projectArray.length)\\n }\\n })),\\n // 任务节点 \\n ...taskArray.map((name, index) => ({\\n name: name,\\n depth: 2,\\n value: nodeValues[name],\\n itemStyle: {\\n color: getColorByDepthAndIndex(2, index, taskArray.length),\\n borderColor: getColorByDepthAndIndex(2, index, taskArray.length)\\n }\\n }))\\n ];\\n // 生成连接数组 \\n const links = [];\\n // 类型 -> 项目的链接 \\n data.forEach(item => {\\n const existingLink = links.find(link => link.source === item.类型 && link.target === item.项目);\\n if (existingLink) {\\n existingLink.value += item.数量;\\n }\\n else {\\n links.push({\\n source: item.类型,\\n target: item.项目,\\n value: item.数量,\\n lineStyle: {\\n color: typeColors[item.类型],\\n opacity: 0.7\\n }\\n });\\n }\\n });\\n // 项目 -> 任务的链接 \\n data.forEach(item => {\\n const existingLink = links.find(link => link.source === item.项目 && link.target === item.任务);\\n if (existingLink) {\\n existingLink.value += item.数量;\\n }\\n else {\\n // 确保正确获取源头类型的颜色 \\n const sourceType = projectToTypeMap[item.项目];\\n if (!typeColors[sourceType]) {\\n console.warn(`找不到类型颜色: ${sourceType} for 项目: ${item.项目}`);\\n }\\n links.push({\\n source: item.项目,\\n target: item.任务,\\n value: item.数量,\\n lineStyle: {\\n color: typeColors[sourceType] || '#999',\\n opacity: 0.7\\n },\\n // 添加源类型信息便于调试 \\n sourceType: sourceType\\n });\\n }\\n });\\n return { nodes, links };\\n};\\n//获取提示文字\\nconst gettooltip = (params) => {\\n console.log(params);\\n if (params.dataType === 'node') {\\n return `${params.name}\\\\n数量: ${params.value}`;\\n }\\n return `${params.data.source} → ${params.data.target}\\\\n数量: ${params.value}`;\\n};\\n// 处理数据 \\nconst { nodes, links } = processData(Context[\\\"recommands\\\"]);\\n// Echarts配置 \\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"项目反馈桑基图\\\",\\n subtext: \\\"展示各个项目任务的不同反馈分类占比\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n tooltip: {\\n trigger: 'item',\\n triggerOn: 'mousemove',\\n formatter: gettooltip\\n },\\n series: [{\\n type: \\\"sankey\\\",\\n animation: true,\\n animationDuration: 300,\\n animationEasingUpdate: 'quinticInOut',\\n left: '5%',\\n top: '12%',\\n right: '20%',\\n bottom: '12%',\\n nodeAlign: 'left',\\n orient: 'horizontal',\\n data: nodes,\\n links: links,\\n nodeGap: 15,\\n nodeWidth: 25,\\n draggable: true,\\n lineStyle: {\\n curveness: 0.5,\\n opacity: 0.7,\\n width: function (params) {\\n return Math.max(10, params.value);\\n },\\n shadowBlur: 3,\\n shadowColor: 'rgba(0,0,0,0.2)'\\n },\\n emphasis: {\\n focus: 'adjacency',\\n lineStyle: {\\n opacity: 0.9,\\n shadowBlur: 10,\\n shadowColor: 'rgba(0,0,0,0.5)'\\n }\\n },\\n label: {\\n position: 'right',\\n fontSize: 12,\\n lineHeight: 16,\\n color: '#000000',\\n distance: 10,\\n formatter: function (params) {\\n var name = params.name;\\n if (name.length > 10) {\\n name = name.substring(0, 10) + '...';\\n }\\n if (params.value && params.value > 0) {\\n return `${name}(${params.value}个)`;\\n }\\n return \\\"\\\";\\n },\\n show: true,\\n align: 'left',\\n verticalAlign: 'middle',\\n backgroundColor: '#ffffffa1',\\n overflow: 'break',\\n padding: [4, 8],\\n borderRadius: 4\\n }\\n }]\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}" } }, "16,1": { @@ -1041,4 +1041,4 @@ "Size": "1473,1000" } ] -}//OvpFVJAt71cxWBj3r9CPg0zcbr5hp+CQ0pVqNPJtMDWlbLIzIv/dbEON0/XnYYeclW0AhpjFNJXJ09aIpyc2yqfM8OcKg9CuVUN09ibiFkCo3NxD2JY/k31LLOriKZI1kmLPazkRf3OEfvFHXfwcGnM51+cw83Y9V7dhgAnmfpNQUUmiKEAVifYGAp60bRmSQkbzzigpLML+QzWeUeMSjjpJlP/4f+zD3xtXxBfYZC8mozGMU8p58kNPO3z2hobbAg6le68iFZscPPE6O/Ry16Xba82m+jf6wkKA5Cmjl0wKFbDQ75h+/aT8h0J1rxDfMFvKPowce0Ep+LljgTMPrJ+p9bnZGHMCiouLkmtImFOLKUVK9FC7pY9zDbIQNNMQB6D3DzXswVA8v8vFukR0+wocBHEI9HEyzXiat3LcYRJklJCDHNPt0oO4ZNlYPAPlRhITvrqMgOAXGsbBoKJWY4Jw17jw7uF5gpoyYBiHczeC9253mEg7jMkRq/qsrRTs8+uDDcNebWfmsmoeH7I87L2f3KalgL1gj5uyJUTJzttok2SphiqhGBAW4MoGC8QrtM3ui8N6CeJwUXp18E46xV+CNFtetTXlxNWES1vJDN3KvmL1aLstBlVtKQ0fckyOUsoxWUd44BaDRcWR4Y9pd//nQcYeoVpoAJc++nUY5mIwAhaJ3T0dwVSG+mzBiREbr86K0QYvFRGzEtCORLY03JLjh6MRoIjuXe/26weQ0TbyqWSllvf9mAAijXi9Y1jbfmYjbmMLrWI+2S07EU4Mb8Wfg58TMDOM+BF9rATJMha5ZzyhF4SvQOm9mTP13PVcVzrzB0yHzMnPofG5MbNOI2P4iP7Z980rkG9jB9xcFjATzkAuHVO37dyCuqv7QXVR5aT7ldQ6TcFewD1P6tPJow==|920 \ No newline at end of file +}//1LYyb7nMoLuI7UKN8tKJvaedZk9J+D8Qb/5brdHHuaQSZ4lrKC9jCypKqUsGyYlH6cAXvg2C2fT9gPi18KzBdIsghVvlaHfjnaGwynCb+XyZ9L1o8zvy/afAM++R7jmjItvy0g2lGxoUmCDIWrzFR7xBrAamDO0JlpLs4SQByUtwtoPLbF1Jdfz017gCBHmFGSiXCpdXG+Aa4ccGls6MrnLOfCSSlVOXiXcVXTDTrNzot9gS9rQLB+PI4/uCl6T66xDlYGlRtYVU2151/yUAQ2sn6qicoCQYcz3PbD0WZGhG13soWNmqxfcrqodyRh8GsSMGUH7vx6to51BNZzCO+YoYECRvCYamjGqiaRCQKl0BTb7iESOzIYSzKMmxe5UR13qg+BE2xu3uwRm5iwPAIyKeSTN7Bm2BJbPxYTGeSI2JQT1LpVY1fzWnWn9AZ69buDNmWzOKDTVS1JGK+8mSjZ+fDcGu2q6CJh19BmrIMgth+x71vegiFZgOmyyO2OGKMfkFKnF4kliFdCR81vu0iHbmpc8DXLw2EGcZdS8yCoGmoL6hpRLgOvWvIUywCKIFnr6VSZRelAFzmTA0epeYznV2o8z89jnb0ohN+x5W9fap+3QrTqS0G5scWxvDIUTXrmmfRjDcRNj/AnRSBdQGvWRmI1gsTbWVknbDJur7HgMFQD3zIBnWqco9SzVnlvMeMbM7YcQASe7xfar1zBlO3gIm5tWybQBVnopes+EPl9aOuiYYGT2Q61u1TRVUNW2ymUQWHU503RiPWOPKucPrFFGAR9BPzdOgNxGl52VUx0TIfoLKa3evELjSPylD0wPtcKvadjxr510SaxtI3hNw3HWTuvX5pf2R7sw3sodMdxWDL3cnxmn/ChmKWtNORBQSPmGa8OWATcrTW9Y0BrPNGA==|920 \ No newline at end of file diff --git a/Reports/人员工时报表.rdlx b/Reports/人员工时报表.rdlx index bea3c57b..ca17a8c1 100644 --- a/Reports/人员工时报表.rdlx +++ b/Reports/人员工时报表.rdlx @@ -8,4 +8,4 @@