手把手教你用策略模式 写echarts的配置项option

前言:策略模式和适配器模式很像   但前者策略的接口和相关类会暴露出来,并且每个策略的“计算内容”都不同【常用于计算】。

 

一、研究下echarts官网的重要配置

  1.1 常用项主要有title  legend xAxis yAxis legend dataset  series  textStyle 如下图所示

手把手教你用策略模式 写echarts的配置项option_第1张图片 手把手教你用策略模式 写echarts的配置项option_第2张图片

 

二、建立Echarts的option类  我在此命名为EchartsOption 【注:后面一般option下直接属性 java命名前缀都是Echarts】

 

package com.ken.sys.common.entity.echarts.option;

import com.ken.sys.common.entity.echarts.axis.EchartsXYAxis;
import com.ken.sys.common.entity.echarts.dataset.EchartDataset;
import com.ken.sys.common.entity.echarts.legend.EchartsLegend;
import com.ken.sys.common.entity.echarts.series.EchartBaseSeries;
import com.ken.sys.common.entity.echarts.textStyle.EchartsTextStyle;
import com.ken.sys.common.entity.echarts.title.EchartsTitle;

import java.util.List;

/**
 *
 * @author swc
 *
 * @date 2020/7/3 0003 下午 13:43
 */
public class EchartsOption {
    //标题
    private EchartsTitle title;

    //图例组件。
    //图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。
    private EchartsLegend legend;

    //直角坐标系 grid 中的 x 轴,
    private EchartsXYAxis xAxis;

    //直角坐标系 grid 中的 y 轴,[x轴和y轴 属性是一样的]
    private EchartsXYAxis yAxis;

    //默认颜色值  全局
    private Object color =new String[]{"#c23531","#2f4554", "#61a0a8", "#d48265", "#91c7ae","#749f83",  "#ca8622", "#bda29a","#6e7074", "#546570", "#c4ccd3"};

    //全局的字体样式。
    private EchartsTextStyle textStyle;

    //系列列表。每个系列通过 type 决定自己的图表类型
    private List series;

    //注意
    //Charts 4 开始支持了 数据集(dataset)组件用于单独的数据集声明,
    // 从而数据可以单独管理,被多个组件复用,并且可以自由指定数据到视觉的映射。这在不少场景下能带来使用上的方便。
    private EchartDataset dataset;

    //省略get set方法

}

2.1 以title 为例子 写相关 的java类EchartsTitle 

手把手教你用策略模式 写echarts的配置项option_第3张图片

/******************************************************************************
 *
 *
 *
 ******************************************************************************
 *
 *****************************************************************************/
package com.ken.sys.common.entity.echarts.title;

/**
 * 
    *
  • Title= EchartsTitle
  • *
  • Description= TODO
  • *
  • Copyright= Copyright (c) 2018
  • *
  • Company= http=//www.jiangqiaotech.com/
  • *
* * @author swc * * @date 2020/7/3 0003 下午 13=54 */ public class EchartsTitle { private String id ; //是否显示标题组件 private boolean show= true ; //主标题文本,支持使用 \n 换行。 private String text= "" ; private String link= "" ; private String target= "blank" ; private Object textStyle; private String subtext= "" ; private String sublink= "" ; private String subtarget= "blank" ; private String subtextStyle; //可选值:"auto"、"left"、"right"、"center"。 private String textAlign= "auto" ; private String textVerticalAlign= "auto" ; private boolean triggerEvent= false ; //number /Array //5 or [5,10,2,20] private Object padding= 5 ; private Integer itemGap= 10 ; private Integer zlevel= 0 ; private Integer z= 2 ; //string | number private Object left= "auto" ; //string | number private Object top= "auto" ; //string | number private Object right= "auto" ; //string | number private Object bottom= "auto" ; //Color private Object backgroundColor= "transparent" ; //Color private Object borderColor= "#ccc" ; private Integer borderWidth= 0 ; private Integer borderRadius= 0 ; private Integer shadowBlur ; //Color private Object shadowColor ; private Integer shadowOffsetX= 0 ; private Integer shadowOffsetY= 0 ; //省略get set方法 }

手把手教你用策略模式 写echarts的配置项option_第4张图片

其他相关类在此不做赘述

 

这里简单说一下 series 使用基类【EchartBaseSeries】 其他如饼图 折线图等的series都是集成EchartBaseSeries

手把手教你用策略模式 写echarts的配置项option_第5张图片

 

三、编写策略类【策略模式】

 

3.1 主要分为三部分,一是策略接口 【EchartsStrategy】  二是策略的上下文 对外暴露 匹配不同的策略 行使不同的方案

三是工厂类将策略注入 做到匹配不同的类型的策略

 

3.1.1 策略接口 【EchartsStrategy】

public interface EchartsStrategy {
//    //创建option
     EchartsOption createOption(IEchartSeries iEchartSeries, List list, HandEchartsDto handEchartsDto);

    //会创建多个option
    List createMulOption(IEchartSeries iEchartSeries, List list, HandEchartsDto handEchartsDto);

}

3.1.2 策略上下文 【EchartStrategyContext】

package com.ken.sys.common.strategycontext.echarts;

import com.ken.sys.common.entity.echarts.dto.HandEchartsDto;
import com.ken.sys.common.entity.echarts.option.EchartsOption;
import com.ken.sys.common.ifs.IEchartSeries;
import com.ken.sys.common.strategy.echarts.base.EchartsStrategy;

import java.util.List;

/**
 * 
    *
  • Title: EchartStrategyContext
  • *
* * @author swc * * @date 2020/7/3 0003 下午 14:54 */ public class EchartStrategyContext { //echart 的生成策略 private EchartsStrategy echartsStrategy; public EchartsOption createOption(IEchartSeries iEchartSeries, List list,HandEchartsDto echartsDto){ if (echartsStrategy != null) { return echartsStrategy.createOption(iEchartSeries,list,echartsDto); } return null; } //会创建多个option public List createMulOption(IEchartSeries iEchartSeries, List list,HandEchartsDto echartsDto){ if (echartsStrategy != null) { return echartsStrategy.createMulOption(iEchartSeries,list,echartsDto); } return null; } public EchartStrategyContext(EchartsStrategy echartsStrategy) { this.echartsStrategy = echartsStrategy; } private EchartStrategyContext() { } }

3.1.3 策略的 工厂类【EchartsStrategyFactory】

 

/******************************************************************************
 *
 *
 *
 ******************************************************************************
 *
 *****************************************************************************/
package com.ken.sys.common.factory.echarts;

import com.ken.sys.common.constant.EchartsConstant;
import com.ken.sys.common.strategy.echarts.*;
import com.ken.sys.common.strategy.echarts.base.EchartsStrategy;

import java.util.HashMap;
import java.util.Map;

/**
 * 
    *
  • Title: EchartsStrategyFactory
  • *
  • Description: TODO
  • *
  • Copyright: Copyright (c) 2018
  • *
  • 微信:tianji_vip
  • *
* * @author swc * * @date 2020/7/3 0003 下午 15:07 */ public class EchartsStrategyFactory { public static Map hashMap; static { hashMap = new HashMap(); hashMap.put(EchartsConstant.LINE,new EchartsLineStrategy()); hashMap.put(EchartsConstant.BAR,new EchartsBarStrategy()); hashMap.put(EchartsConstant.PIE,new EchartsPieStrategy()); hashMap.put(EchartsConstant.FUNNEL,new EchartsFunnelStrategy()); hashMap.put(EchartsConstant.GAUGE,new EchartsGaugeStrategy()); hashMap.put(EchartsConstant.HEATMAP,new EchartsHeatMapStrategy()); } public static EchartsStrategy getEchartsStrategy(String type) { return hashMap.get(type); } }

四 、部分策略内容展示【这里是把策略封装在BaseStrategy里面 作为公共部分】

手把手教你用策略模式 写echarts的配置项option_第6张图片

BaseStrategy的相关方法
package com.ken.sys.common.strategy.echarts.base;

import com.ken.sys.common.entity.echarts.axis.EchartsXYAxis;
import com.ken.sys.common.entity.echarts.dto.HandEchartsDto;
import com.ken.sys.common.entity.echarts.legend.EchartsLegend;
import com.ken.sys.common.entity.echarts.option.EchartsOption;
import com.ken.sys.common.entity.echarts.series.EchartBaseSeries;
import com.ken.sys.common.entity.echarts.series.HeatMapSeries;
import com.ken.sys.common.entity.echarts.series.data.SeriesData;
import com.ken.sys.common.entity.echarts.series.property.SeriesAreaStyle;
import com.ken.sys.common.entity.echarts.series.property.SeriesItemStyle;
import com.ken.sys.common.entity.echarts.series.property.SeriesLabel;
import com.ken.sys.common.entity.echarts.series.property.SeriesLineStyle;
import com.ken.sys.common.entity.echarts.title.EchartsTitle;
import com.ken.sys.common.ifs.IEchartSeries;
import com.ken.sys.common.util.EmptyUtils;
import com.ken.sys.common.util.ReflectUtils;

import java.util.*;

/**
 * 
    *
  • Title: BaseStrategy
  • *
  • Description: TODO
  • *
* * @author swc * * @date 2020/7/3 0003 下午 15:57 */ public class BaseStrategy { //针对line和bar图像 public EchartsOption createOptionForLineAndBar(IEchartSeries iEchartSeries,Class seriesClass, List list, HandEchartsDto handEchartsDto){ String xyAxisName = handEchartsDto.getxAxisDataName(); Object[] legends = handEchartsDto.getLegends(); Object[] fields = handEchartsDto.getFields(); List[] saveList = handEchartsDto.getSaveList(); EchartsOption option =new EchartsOption(); List xAxisDataList =new ArrayList(); Map> map =new HashMap>(); Number value =null; SeriesData data=null; String nameValue =null; try { for(T t:list){ nameValue = ReflectUtils.getFieldValue(t,xyAxisName).toString(); xAxisDataList.add(nameValue); for(int ind=0;ind mulseries =new ArrayList(); commonSetSeries(iEchartSeries, seriesClass, legends, fields, mulseries, saveList); EchartsLegend legend = new EchartsLegend(); legend.setData(Arrays.asList(legends)); EchartsXYAxis xAxis = new EchartsXYAxis(); xAxis.setData(xAxisDataList); option.setLegend(legend); option.setxAxis(xAxis); option.setSeries(mulseries); }catch (Exception e){ //实际换成日志打印 e.printStackTrace(); } return option; } //针对漏斗图、仪器图 和饼图图像 public EchartsOption createOptionFGP(IEchartSeries iEchartSeries, Class seriesClass, List list, HandEchartsDto handEchartsDto){ EchartsOption option =new EchartsOption(); String xyAxisName = handEchartsDto.getxAxisDataName(); Object[] legends = handEchartsDto.getLegends(); Object[] fields = handEchartsDto.getFields(); List[] saveList = handEchartsDto.getSaveList(); boolean requireXAxis = handEchartsDto.getRequireXAxis(); List xAxisDataList =new ArrayList(); Map> map =new HashMap>(); Number value =null; SeriesData data=null; String xAxisDataValue =null; try { for(T t:list){ xAxisDataValue = ReflectUtils.getFieldValue(t,xyAxisName).toString(); for(int ind=0;ind mulseries =new ArrayList(); commonSetSeries(iEchartSeries, seriesClass, legends, fields, mulseries, saveList); EchartsLegend legend =new EchartsLegend(); legend.setData(Arrays.asList(legends)); EchartsXYAxis xAxis =new EchartsXYAxis(); xAxis.setData(xAxisDataList); //需要x轴 if(requireXAxis){ option.setxAxis(xAxis); } option.setLegend(legend); option.setSeries(mulseries); }catch (Exception e){ e.printStackTrace(); } return option; } /** * 功能描述: 创建热力图的option * @param iEchartSeries 接口 * @param t 对象 // * @param titleFieldName // * @param subFieldName 对象里面需要处理的list数据 // * @param xDimension 维度x轴 // * @param yDimension 维度y // * @param xAxisDataName x轴需要展示的信息 // * @param yAxisDataName y轴需要展示的信息 // * @param showValField 需要展示数据的列 * @return: java.util.Map * @author: swc * @date: 2020/7/2 0002 下午 12:52 */ public static EchartsOption createHeatMapOption(IEchartSeries iEchartSeries, T t, HandEchartsDto handEchartsDto) { EchartsOption option =new EchartsOption(); List seriesList =new ArrayList(); String titleFieldName = handEchartsDto.getTitleFieldName(); String subFieldName = handEchartsDto.getSubFieldName(); String xDimension = handEchartsDto.getxDimension(); String yDimension = handEchartsDto.getyDimension(); String xAxisDataName = handEchartsDto.getxAxisDataName(); String yAxisDataName = handEchartsDto.getyAxisDataName(); String showValField = handEchartsDto.getShowValField(); String showDateField = handEchartsDto.getShowDateField(); String coordinateSystem = handEchartsDto.getCoordinateSystem(); Map map =new HashMap(); //标题 String titleName =null; if(!EmptyUtils.isNullOrEmpty(titleFieldName)){ titleName = ReflectUtils.getFieldValue(t,titleFieldName).toString(); } List subList = (List)ReflectUtils.getFieldValue(t,subFieldName); Set xAxisData =new TreeSet(); Set yAxisData =new TreeSet(); //数据值---单个数据 List seriesDataValue ; EchartBaseSeries echartBaseSeries = new HeatMapSeries(); if("calendar".equals(coordinateSystem)){ ((HeatMapSeries)echartBaseSeries).setCoordinateSystem("calendar"); ((HeatMapSeries)echartBaseSeries).setCalendarIndex(handEchartsDto.getCalendarIndex()); } List seriesDataList = new ArrayList(); SeriesData seriesData =null; String xAxisValue =null; String yAxisValue =null; // 维度X String xDim = null; // 维度y String yDim = null; for(int i=0;i * @author: swc * @date: 2020/7/2 0002 下午 12:52 */ public static List createHeatMapOption(IEchartSeries iEchartSeries, List list, HandEchartsDto handEchartsDto) { List optionList =new ArrayList(); String coordinateSystem = handEchartsDto.getCoordinateSystem(); //拼接不同年份日历的series的值 List seriesList =new ArrayList(); EchartsOption option = null; for(int i=0;i seriesClass, Object[] legends, Object[] fields, List mulseries, List[] saveList) throws InstantiationException, IllegalAccessException { EchartBaseSeries echartBaseSeries; for (int ind = 0; ind < fields.length; ind++) { //获取指定的series echartBaseSeries = seriesClass.newInstance(); echartBaseSeries.setName((String) legends[ind]); echartBaseSeries.setData(saveList[ind]); //设置整体样式[如一条折线或条状图的样式] if (!EmptyUtils.isNullOrEmpty(iEchartSeries)) { iEchartSeries.setSeriesDetailProp(echartBaseSeries, new SeriesLabel(), new SeriesItemStyle(), new SeriesAreaStyle(), new SeriesLineStyle()); } mulseries.add(echartBaseSeries); } } }

五、为了方便 最后写了工具类【EChartsNewUtil】 把策略调用进行封装

注:1.这里主要看有注释的方法 因为参数是最全的  2.关于IEchartSeries ,EchartsStrategy 这两类,IEchartSeries 是针对series的数据处理 或添加修改样式毕竟每个公司 /每个系统业务多多少少会有些不同) ,EchartsStrategy 这个是自定义你自己业务需求的策略(需要继承EchartsStrategy ,这个完全是重新定义这个方法 IEchartSeries 再次不起作用 除非你自动代码回调到它

   5.1 HandEchartsDto是封装的参数,用于反射数据源的属性或处理部分业务

/******************************************************************************
 *
 *
 *
 ******************************************************************************
 *
 *****************************************************************************/
package com.ken.sys.common.entity.echarts.dto;

import java.util.List;

/**
 * 
    *
  • Title: HandEchartsDto
  • *
  • Description: TODO
  • *
  • Copyright: Copyright (c) 2018
  • *
  • 微信:tianji_vip
  • *
* * @author swc * * @date 2020/7/2 0002 下午 13:44 */ public class HandEchartsDto { // 该系列使用的坐标系,可选: // 'cartesian2d' // 使用二维的直角坐标系(也称笛卡尔坐标系),通过 xAxisIndex, yAxisIndex指定相应的坐标轴组件。 // 'geo' // 使用地理坐标系,通过 geoIndex 指定相应的地理坐标系组件。 // ‘calendar’ // 使用日历坐标系 private String coordinateSystem ="cartesian2d"; //标题[主-列名] private String titleFieldName; //子对象的属性名[列名] private String subFieldName; //维度x轴[列名] private String xDimension; //维度y轴[列名] private String yDimension; //x轴需要展示的信息[列名] private String xAxisDataName; //y轴需要展示的信息[列名] private String yAxisDataName; //需要展示数据的列的属性名[时间列] private String showDateField; //需要展示数据的列的属性名[列名] private String showValField; //使用的日历坐标系的 index,在单个图表实例中存在多个日历坐标系的时候有用。 private int calendarIndex; //legend的值 private Object[] legends; //一般为legend 一一对应的属性项的值 private Object[] fields; //一般为fields 一一对应的列的 单个serie的data里面的value值 一般为数组 private List[] saveList; //是否需要x轴 private boolean requireXAxis =true; //此处省略get set方法 }
package com.ken.sys.common.util;
import com.ken.sys.common.entity.echarts.dto.HandEchartsDto;
import com.ken.sys.common.entity.echarts.option.EchartsOption;
import com.ken.sys.common.factory.echarts.EchartsStrategyFactory;
import com.ken.sys.common.ifs.IEchartSeries;
import com.ken.sys.common.strategy.echarts.base.EchartsStrategy;
import com.ken.sys.common.strategycontext.echarts.EchartStrategyContext;

import java.util.*;

public class EChartsNewUtil {

    /**
     * 功能描述: 
     * @param type 图形类别
     * @param iEchartSeries 外部接口 用于重写参数 或 样式等
     * @param list  数据源
     * @param handEchartsDto  需要处理的相应字段【list或list的子集里面】
     * @return: com.ken.sys.common.entity.echarts.option.EchartsOption
     * @param strategy  自定义的策略
     * @author: swc
     * @date: 2020/7/4 0:48
    */ 
    public static EchartsOption creatOption(String type, IEchartSeries iEchartSeries, List list, HandEchartsDto handEchartsDto, EchartsStrategy strategy) {
        //获取匹配的策略
        if(EmptyUtils.isNullOrEmpty(strategy)){
            strategy =EchartsStrategyFactory.getEchartsStrategy(type);
        }
        EchartStrategyContext context = new EchartStrategyContext(strategy);
        return context.createOption(iEchartSeries,list,handEchartsDto);
    }

    public static EchartsOption creatOption(String type, List list, HandEchartsDto handEchartsDto) {
        return creatOption(type,null,list,handEchartsDto,null);
    }

    public static EchartsOption creatOption(String type, List list, HandEchartsDto handEchartsDto,EchartsStrategy strategy) {
        return creatOption(type,null,list,handEchartsDto,strategy);
    }

    public static EchartsOption creatOption(String type,IEchartSeries iEchartSeries, List list, HandEchartsDto handEchartsDto) {
        return creatOption(type,iEchartSeries,list,handEchartsDto,null);
    }

    /**
     * 功能描述:
     * @param type 图形类别
     * @param iEchartSeries 外部接口 用于重写参数 或 样式等
     * @param list  数据源
     * @param handEchartsDto  需要处理的相应字段【list或list的子集里面】
     * @param strategy  自定义的策略
     * @return: com.ken.sys.common.entity.echarts.option.EchartsOption
     * @author: swc
     * @date: 2020/7/4 0:48
     */
    public static List creatMulOptionForHeatMap(String type, IEchartSeries iEchartSeries, List list, HandEchartsDto handEchartsDto,EchartsStrategy strategy) {
        //获取匹配的策略
        if(EmptyUtils.isNullOrEmpty(strategy)){
            strategy =EchartsStrategyFactory.getEchartsStrategy(type);
        }
        EchartStrategyContext context = new EchartStrategyContext(strategy);
        return context.createMulOption(iEchartSeries,list,handEchartsDto);
    }

    public static List creatMulOptionForHeatMap(String type, IEchartSeries iEchartSeries, List list, HandEchartsDto handEchartsDto) {
        return creatMulOptionForHeatMap(type,iEchartSeries,list,handEchartsDto,null);
    }


    public static List creatMulOptionForHeatMap(String type, List list, HandEchartsDto handEchartsDto, EchartsStrategy strategy) {
        return creatMulOptionForHeatMap(type,null,list,handEchartsDto,strategy);
    }

    public static List creatMulOptionForHeatMap(String type, List list, HandEchartsDto handEchartsDto) {
        return creatMulOptionForHeatMap(type,null,list,handEchartsDto,null);
    }

}

 

 

 

六、测试数据和测试该工具类

部分代码


    //柱状图 折线图
    @Test
    public void barOrLine()throws Exception{
        String type=EChartsUtil.LINE;//BAR
        List list= getData();

        Object[] legends ={"总金额","实付金额"};
        Object[] fields ={"nums1","nums2"};

        List[] saveList =new List[]{new ArrayList(),new ArrayList()};

        HandEchartsDto dto =new HandEchartsDto();

        dto.setxAxisDataName("name");
        dto.setLegends(legends);
        dto.setFields(fields);
        dto.setSaveList(saveList);

        EchartsOption option = EChartsNewUtil.creatOption(type, new IEchartSeries() {
            @Override
            public void setSeriesDetailProp(EchartBaseSeries series, SeriesLabel label, SeriesItemStyle itemStyle, SeriesAreaStyle areaStyle, SeriesLineStyle lineStyle) {
//                ((BarSeries) series).setBarMaxWidth("60%");
//                label.setShow(true);
//                label.setPosition("top");
//                series.setLabel(label);
            }

            @Override
            public void setSeriesDataProp(SeriesData seriesData, SeriesLabel label, SeriesItemStyle itemStyle, SeriesAreaStyle areaStyle, SeriesLineStyle lineStyle) {

            }
        }, list, dto);
        option.setSeries(null);
     
    }

 源码:https://gitee.com/ten-ken/java-wheel/tree/master/ken [先找测试类TestStrategyEcharts]

微信: tianji_vip

 

手把手教你用策略模式 写echarts的配置项option_第7张图片

你可能感兴趣的:(设计模式,java)