package com.ruoyi.common.utils.asPose;

import com.aspose.words.Shape;
import com.aspose.words.*;

import java.awt.*;

/**
 * @Author fuzhilin
 * @Date 2021/11/30 0030 16:05
 * @Description
 */
public class ReplaceAndInsertChart implements IReplacingCallback {

    private String key;
    private GenerateChartVO chartVO;

    public ReplaceAndInsertChart(String key, GenerateChartVO chartVO) {
        this.key = key;
        this.chartVO = chartVO;
    }

    @Override
    public int replacing(ReplacingArgs e) throws Exception {
        //获取当前节点
        Node currentNode = e.getMatchNode();
        //节点拆分处理当前匹配字段
        splitRun(currentNode, e.getMatchOffset());
        //获取当前文档
        Document document = (Document) currentNode.getDocument();
        DocumentBuilder builder = new DocumentBuilder(document);
        //将光标移动到指定节点
        builder.moveTo(currentNode);
        // 统计图标题
        String[] title = chartVO.getTitle();
        // 统计图类型(参考：ChartType)
        int chartType = chartVO.getChartType();
        // 统计图字段
        String[] categories = chartVO.getCategories();
        // 统计图字段数据（二维数组支持多折线）
        double[][] values = chartVO.getValues();
        //设置统计图宽和高
        double height = chartVO.getHeight();
        if (0 == height) {
            height = 415;
        }
        double width = chartVO.getWidth();
        if (0 == width) {
            width = 415;
        }
        Boolean dataPercent = chartVO.getDataPercent();
        Boolean coordinatePercent = chartVO.getCoordinatePercent();
        Boolean showLegendKey = chartVO.getShowLegendKey();
        //插入
        addChart(builder, chartType, title, categories, values, height, width, dataPercent, coordinatePercent,showLegendKey);
        return ReplaceAction.SKIP;
    }

    /**
     * 加载统计图
     *
     * @param builder
     * @param chatType   统计图类型
     * @param title      统计图标题
     * @param categories 统计图字段
     * @param values     统计图字段数据
     */
    private static void addChart(DocumentBuilder builder, int chatType, String[] title, String[] categories, double[][] values, double height, double width, Boolean dataPercent, Boolean coordinatePercent,Boolean showLegendKey) {
        //设置首行缩进
       /* builder.getParagraphFormat().setFirstLineIndent(0);
        builder.writeln("");*/
        try {
            Shape shape = builder.insertChart(chatType, width, height);
            shape.setVerticalAlignment(VerticalAlignment.CENTER);
            shape.setHorizontalAlignment(HorizontalAlignment.CENTER);
            // 不覆盖
            shape.setAllowOverlap(false);
            Chart chart = shape.getChart();
            ChartSeriesCollection seriesCollection = chart.getSeries();
            // 清除默认
            seriesCollection.clear();
            // 显示在下面
            chart.getLegend().setPosition(LegendPosition.BOTTOM);
            // 添加数据
            ChartTitle ct = chart.getTitle();
            if (coordinatePercent){
                chart.getAxisY().getNumberFormat().setFormatCode("0.00%");
                chart.getAxisX().getNumberFormat().setFormatCode("0.00%");
            }
            ct.setOverlay(false);
            //如果是柱形图则不显示标题
            if (ChartType.COLUMN == chatType) {
                if (!coordinatePercent){
                    chart.getAxisY().getScaling().setMinimum(new AxisBound(1));
                }
                ct.setShow(false);
            }
            ChartLegend cl = chart.getLegend();
            cl.setOverlay(false);
            Color[] customColors=new Color[]{new Color(147,205,221),new Color(250,192,144),new Color(25 ,202 ,173 )
                    ,new Color(214  ,213  ,183 ),new Color(209   ,186   ,116 ),new Color(230   ,206   ,172 ),new Color(236   ,173   ,158 )
                    ,new Color(244   ,96   ,108 ),new Color(190    ,237    ,199 ),new Color(140    ,199    ,181 ),new Color(160   ,238    ,225 ),new Color(230,224,236)
            };
            if(null==values){
                values=new double[][]{};
            }
            //向形状中添加数据
            for (int i = 0; i < title.length; i++) {
                ChartSeries chatSeries = seriesCollection.add(title[i], categories, values[i]);
                // 设置数据显示
                ChartDataLabelCollection dataLabelCollection = chatSeries.getDataLabels();
                for (int j = 0; j < categories.length; j++) {
                    if(j>10){
                        chatSeries.getDataPoints().get(j).getFormat().getFill().setForeColor(AsposeUtil.getColor());
                    }else{
                        chatSeries.getDataPoints().get(j).getFormat().getFill().setForeColor(customColors[j%10]);
                    }
                }
                // 根据参数 showPercent 决定是否显示百分比，如果为 true，则显示百分比；否则，显示Y轴值。
                if (dataPercent){
                        dataLabelCollection.getNumberFormat().setFormatCode("0.00%");
                }
                // 所有参数为0不展示值
                if (!allValueIsZero(values[i])) {
                    dataLabelCollection.setShowValue(true);
                }
                // 设置数据标签的分隔符为换行符，即每个标签显示在一行。
                dataLabelCollection.setSeparator("\r\n");
                dataLabelCollection.setShowLegendKey(showLegendKey);   // 是否显示图例
                dataLabelCollection.setShowCategoryName(false);//是否显示系列的名称在系列旁边
                dataLabelCollection.setShowLeaderLines(false);
                dataLabelCollection.setShowSeriesName(false);//是否将图形标题显示在系列名称中
                dataLabelCollection.setShowBubbleSize(false);
                // 设置段落格式的首行缩进为5个磅
                //builder.getParagraphFormat().setFirstLineIndent(5);
            }
            if (ChartType.LINE_STACKED == chatType||ChartType.LINE == chatType) {
                ChartSeriesCollection series = chart.getSeries();
                for (int i = 0; i < series.getCount(); i++) {
                    chart.getSeries().get(i).getFormat().getFill().setForeColor(customColors[i%10]);
                }
            }
            /*builder.writeln("");
            builder.getParagraphFormat().setFirstLineIndent(0);*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void splitRun(Node currentNode, int position) {
        String text = currentNode.getText();
        Node newNode = currentNode.deepClone(true);
        if (text.length() >= position + this.key.length()) {
            ((Run) currentNode).setText(text.substring(position + this.key.length()));
        } else {
            int morlength = position + this.key.length() - text.length();
            ((Run) currentNode).setText("");
            Node tmpnode = currentNode;
            for (int i = 0; i < this.key.length(); i++) {
//                System.out.println(i);
                tmpnode = tmpnode.getNextSibling();
                String tmptext = tmpnode.getText();
//                System.out.println(tmptext);
//                System.out.println(morlength);
//                System.out.println("--------" + (tmptext.length() >= morlength));

                if (tmptext.length() >= morlength) {
                    ((Run) tmpnode).setText(tmptext.substring(morlength));
                    break;
                } else {
                    morlength = morlength - tmptext.length();
                    ((Run) tmpnode).setText("");
                }
            }
        }
        if (position > 0) {
            ((Run) newNode).setText(text.substring(0, position));
            currentNode.getParentNode().insertBefore(newNode, currentNode);
        }
    }

    /**
     * 判断图形（柱状图）所有值为0
     *
     * @param value
     * @return
     */
    public static boolean allValueIsZero(double[] value) {
        boolean res = true;
        for (double tmp : value) {
            if (tmp > 0) {
                res = false;
                break;
            }
        }
        return res;
    }

    public static void main(String[] args) throws Exception {
        // 创建文档对象
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);

        //将光标移动到指定节点

        // 统计图标题

        String[] title = {"1"};

        // 统计图字段
        String[] categories = {"1"};
        // 统计图字段数据（二维数组支持多折线）
        double[][] values = {
                {0.2},  // 第一个数据系列的值
                // 第二个数据系列的值
        };
        //插入
        addChart(builder, ChartType.PIE_3_D, title, categories, values, 215, 316,true,false,false);

        // 保存文档
        doc.save("D://saveFile//test//StackedLineChart.docx");
    }
}
