全部文档
文档中心图表操作图表自定义JS

图表自定义JS

由于图表的展现形式、样式丰富多样,已提供的标准功能不可能覆盖全部场景。 对于部分标准功能不能满足的展现场景,用户可以使用图表组件的自定义JS功能来实现。

编辑模式下,点击图表组件左侧的JS图标,在弹窗中开启自定义JS即可。

  • 柱形图

  • 堆积柱形图

  • 条形图

  • 堆积条形图

  • 折线图

  • 平滑折线图

  • 堆积折线图

  • 堆积平滑折线图

  • 堆积面积图

  • 组合图

  • 地图

  • 气泡图

  • 散点图

  • 瀑布图

  • 饼图

  • 环状饼图

  • 南丁格尔饼图

在图表组件中,目前已支持提供以下信息以供用户在自定义JS功能中修改图表的最终呈现:

  • 当前图表所属应用信息

  • 当前图表所属空间信息

  • 当前系统登录用户信息

  • 当前图表的条件配置信息

  • 当前图表已接收到数据源返回的业务数据信息

  • 当前图表使用Echarts进行渲染的Option信息(仅前述图表类型)

  • 内置rootRequest根请求,用于调用系统API

// params 为内置变量,业务中的参数及方法都会挂载到上面
export default (params) => {
const {
 globalInfo: {
   appId, // 当前BI图表所属应用ID
   space, // 当前BI图表所属空间
   userInfo, // 当前系统登录用户信息
 }, 
 
 // -----内置请求------
 router, // React Router
 rootRequest, // 系统根请求
} = params;

// 返回对象用于交互(必须)
return {
 // 内置 入口方法(必须)
 // run的执行时机:在图表最终渲染前执行(即echart.setOption前执行)
 run({
        options, // 当前BI图表ECharts渲染Option(仅图形)
   	   config, // 当前BI图表的配置信息
   	   apiData, // 当前BI图表的数据信息
     }) {
   // 自定义逻辑
   
   // 返回仅接收ECharts Options
   return {
     options: {
       //用于在浏览器控制台打印当前图表的 option参数
       //console.log(options);

       // 此处为ECharts配置类容,具体参考ECharts配置官网
       // https://echarts.apache.org/zh/option.html#title
       //...options 代表解构已返回option参数
       ...options,
       //下方指定的参数将覆盖options已有设置参数,如果原设置中没有该设置项,将添加到options并返回
       name: 'xxx'
     }
   }
 },
 // 用户自定义JS
 //aaa() {
   // TODO 自定义业务逻辑
 }
};
}

config中包括图表的配置信息内容如下:

----------------------------(run参数类型定义)-------------------------------
// BI图表配置类型
export interface IChartConfig {
  chartType?: ChartTypes;
  baseInfo: IBaseInfo;
  conditions: IConditionDataConfig;
  operateType: string;
  sourceDetail?: ISourceDetail[];
  styleConfig?: object;
}

// BI图表基础信息
export interface IBaseInfo {
  description?: IDescription;
  elementName: string;
  elementType: string;
  folderId: string;
  displayType: number;
  moduleId: string;
  path: string;
  useCustomJs: boolean;
  chartJsCode: string;
  chartJsPath: string;
}

// BI图表条件区配置信息
export interface IConditionDataConfig {
  columns: IColumnsEntity[];
  dataFilter: IColumnsEntity[];
  measures?: IColumnsEntity[];
  pages: IColumnsEntity[];
  rows: IColumnsEntity[];
}

// 各条件区内单组合配置信息
export interface IColumnsEntity {
  hiddenEmpty: boolean;
  hiddenNoRight: boolean;
  hiddenNoRow: boolean;
  items: ItemsEntity[];
  fieldConfig?: IChartFieldConfig;
}

// 度量字段设置
export interface IChartFieldConfig {
  chartType?: string;
  displayMaximum?: boolean;
  displayMinimum?: boolean;
  displayAverage?: boolean;
  smooth?: boolean;
  stack?: boolean | string;
}

// 各条件区内各组合中单字段的配置信息
export interface ItemsEntity {
  collectMethod: string;
  columnName: string;
  tableAlias?: string;
  dimensionExpression?: string;
  isMeasure?: boolean;
  description: IDescription;
  currentValue?: ValueTypeItem['defaultValue'];
  displayType?: string;
  valueType: ValueTypeItem['valueType'];
  valueTypeMap: IValueTypeMap;
  formatType?: DateFormatType;
  filterCondition?: IFilterCondition;
  fieldConfig?: IChartFieldConfig;
  // 前端临时id
  uuid?: string;
  memberInfo?: {
    accountType: string;
    dataType: string;
    multilingual: Record<string, string>;
    name: string;
  };
	// 虚拟度量配置信息
  measureList?: ItemsEntity[];
  items?: ItemsEntity[];
}

场景一:基于数据源返回的数据指定饼图扇区颜色

export default (params) => {
const { getAreaInfoByCode, setAreaInfo } = params;
return {
 run({options}) {
   //console.log(options);
   return {
     options: {
       ...options, // 可修改 或 完全替换
       series: {
         ...options.series,
         //用于定义基于options中的series.data数据,格式化颜色的规则
         data: options.series.data.map(d => {
           if(d.value >= 1000000) {
             return {
               ...d,
               itemStyle: {
                 color: 'black'
               }
             }
           } else {
             return d
           }
         })
       }
     }
   }
 }
}
}

场景二:自定义设置柱形图表中缩略轴

export default (params) => {
const { getAreaInfoByCode, setAreaInfo } = params;
return {
 run({options}) {
   //console.log(options);
   return {
     options: {
       ...options, // 可修改 或 完全替换
       dataZoom:{
           ...dataZoom,
           type:'inside',
         show:true,
         yAxisIndex:0,
         filterMode:'none'  //配置过滤模式
       }
       
     }
   }
 }
}
}

场景三:根据返回的数据显示双环图

export default () => {
  function rule(series,xaxis_name,ind) {
     let result = [];
     for (let i = 0; i < series[ind].data.length; i++) {
         result.push({'value': series[ind].data[i].value, 'name': xaxis_name.data[i]})
        }
       return result;
      }
  
  
  return {
    run({options}) {
      console.log(options.series);
      let newData1 = rule(options.series,options.xAxis,0);
      let newData2 = rule(options.series,options.xAxis,1);
      console.log(newData2);
      const col = ['#F76A5B','#F68C5D','#FFA933', '#FACF9F',
      '#CBDBB3', '#7BB889','#599485'];
      const rad=[[0, '30%'],['45%', '60%']];
      const piename=['Actual','Budget']
      return {
        options: {
          ...options,
          xAxis:{ show:false},
          yAxis:{ show:false},
          legend:{ 
            show:true,
            data:piename
          },
          tooltip:{
            show:true,
            trigger: 'item',
            formatter: '{a} <br/>{b}: {c} ({d}%)'
          },

          series:options.series.map((serie, index) => ({
            ...serie,
            name:piename[index],
            type:'pie',
            radius: rad[index],
            data:index === 0 ? newData1:newData2,
             label: {
                 formatter: '{a}-{b}:{c}'},
            tooltip:{
               //formatter: '{a}-{b}:{c}'
            },
            
          })),
          color:col
        }
      }
    }
  }
}

场景四:增加信息提示框(如图中蓝色方框内所示)

export default () => {
  // 数值修改 
  function division(value) {
    if(value >= 1000000){
      value = Math.trunc((value / 1000000));
    }
    return value+ 'M';
  }


  return {
    run({options}) {
      const col = ['#C1C1C1','#EF8943', '#E34838'];
      console.log("options", options);
      return {
        options: {
          ...options,
          // 关键代码 纵坐标数值修改
          xAxis:{
            ...options.xAxis,
             axisTick:{
              show:true,
              alignWithLabel:true
             },
          },
          yAxis:options.yAxis.map((yAxis, index) => {
            return {
              ...yAxis,
              axisLabel: {
                formatter:(value) => {
                  //return division(value);
                  return index===0 ? division(value) : value;
                }
              }
            };
          }),
          dataZoom:[{
            type:'inside',
            show:true,
            start:50,
            end:100,
            height:15,
          }],
          
          series:options.series.map((series, index) => {
            return {
              ...series,
              barGap:0,
              markArea: index === 0 ?{
                  data: [
                  [
                        {
                          name:'疫情来袭',
                          xAxis: '2021-6',
                          itemStyle: {color: 'rgb(255,242,204,0.5)'},
                          silent:true,
                                label: {
                                  show:true,
                                  position:['50%', '106%'],
                                  align:'center',
                                  verticalAlign:'center',
                                  backgroundColor:'#FFF2CC', 
                                  borderColor:'#FFD966',
                                  borderWidth:2,
                                  padding: [3, 2],
                                  width:60,
                                  height:15,}
                           
                        },
                        {
                          xAxis: '2021-8'
                        }
                  ]
                  ] 
                }:{},
            };
          }),
          color:col,

        }
      }
    }
  }
}

场景五:实现预实对比

export default () => {
  return {
    run({options}) {
      const col = [ '#C1C1C1','#D45A34'];
      const lege = ['Standard','Actual'];
      return {
        options: {
          ...options,
          series:options.series.map((serie, index) => ({
            ...serie,
            barWidth:'60%',
            barGap:'-125%',
            barCategoryGap: '50%',
            name: lege[index],
            label:{
              ...serie.label,
              show:true,
              position:'top',
              formatter:(value) => {
                return index === 1 ? value.data.value.toFixed(1) : '';
              }
            }
          })),
          
          legend:{
            ...options.legend,
            data: ['Standard','Actual'],
            show:true,
            top: 0,
            type: 'scroll',
          },
         
          color:col
        }
      }
    }
  }
}

回到顶部

咨询热线

400-821-9199

我们使用 ChatGPT,基于文档中心的内容以及对话上下文回答您的问题。

ctrl+Enter to send