package com.yeejoin.equipmanage.common.utils;


import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.springframework.util.ObjectUtils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.*;

/**
 * @author lisong
 * @date 2022-08-23.
 */
public class ChartsUtils {


    public static String pieChart(List<Map<String, Object>> data, String title) {
        //如 果不使用Font,中文将显示不出来
        Font font = new Font("新宋体", Font.BOLD, 15);

        // 创建数据：饼状图就是名称和值（比例）

        Map<String, Double> map = new HashMap<String, Double>();
//        for (int i = 0; i < name.size(); i++) {
//            map.put(name.get(i), value.get(i));
//        }
        for (Map<String, Object> item : data) {
           map.put(String.valueOf(item.get("type")),Double.parseDouble(ObjectUtils.isEmpty(item.get("value"))?"0":String.valueOf(item.get("value"))));


        }
        // 创建JFreeChart
        JFreeChart chart = createPieChart(title, map, font);
        BufferedImage image = chart.createBufferedImage(600, 600);
        byte[] bytes = null;
        try {
            bytes = ChartUtilities.encodeAsPNG(image);
        } catch (IOException e1) {
            System.out.println("生成饼图失败");
        }
        return Base64.getEncoder().encodeToString(bytes);

    }


    private static byte[] fileToByte(File file) {
        byte[] fileBytes = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            fileBytes = new byte[(int) file.length()];
            fis.read(fileBytes);
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return fileBytes;
    }


    /**
     * 生成饼图
     *
     * @param title
     * @param data
     * @param font
     * @return
     */
    public static JFreeChart createPieChart(String title, Map<String, Double> data, Font font) {
        try {
            Set<Map.Entry<String, Double>> set = data.entrySet();
            DefaultPieDataset pds = new DefaultPieDataset();
            Iterator iterator = set.iterator();
            Map.Entry entry;
            while (iterator.hasNext()) {
                entry = (Map.Entry) iterator.next();
                pds.setValue(entry.getKey().toString(), Double.parseDouble(entry.getValue().toString()));
            }
            // 生成一个饼图的图表：显示图表的标题、组装的数据、是否显示图例、是否生成贴士以及是否生成URL链接
            JFreeChart chart = ChartFactory.createPieChart(title, pds, true, false, true);
            // 设置图片标题的字体
            chart.getTitle().setFont(font);
            // 得到图块,准备设置标签的字体
            PiePlot plot = (PiePlot) chart.getPlot();
            //设置分裂效果,需要指定分裂出去的key
//            plot.setExplodePercent("摄像机", 0.1);  分裂效果，可选
            // 设置标签字体
            plot.setLabelFont(font);
            // 设置图例项目字体
            chart.getLegend().setItemFont(font);
            // 设置开始角度
//            plot.setStartAngle(new Float(3.14f / 2f));  开始角度，意义不大
            //设置plot的前景色透明度
            plot.setForegroundAlpha(0.7f);
            //设置plot的背景色透明度
            plot.setBackgroundAlpha(0.0f);
            //设置标签生成器(默认{0})
            //{0}:key {1}:value {2}:百分比 {3}:sum
            plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}({1})/{2}"));  // 一般在{1}后面加单位，如：{0}({1}次)/{2}
            //将内存中的图片写到本地硬盘
//            ChartUtilities.saveChartAsJPEG(new File("H:/a.png"), chart, 600, 300);
            // 标注位于上侧
            // chart.getLegend().setPosition(RectangleEdge.TOP);
            // 设置标注无边框
            chart.getLegend().setFrame(new BlockBorder(Color.WHITE));
            return chart;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String manyLineChart(List<Map<String, Object>> value, String title, String xtitle, String ytitle, String type) {
        // 绘图数据集
        DefaultCategoryDataset dataSet = new DefaultCategoryDataset();

        for (Map<String, Object> map : value) {
            if ("month".equals(type)) {
                dataSet.setValue(Double.valueOf(String.valueOf(map.get("y"))), String.valueOf(map.get("title")), String.valueOf(map.get("x")).substring(8, 10));
            } else {
                dataSet.setValue(Double.valueOf(String.valueOf(map.get("y"))), String.valueOf(map.get("title")), String.valueOf(map.get("x")).substring(5, 10));
            }
        }

        JFreeChart chart = createManyLineChart(dataSet, title, xtitle, ytitle);

        BufferedImage image = chart.createBufferedImage(1000, 800);
        byte[] bytes = null;
        try {
            bytes = ChartUtilities.encodeAsPNG(image);
        } catch (IOException e1) {
            System.out.println("生成折线图失败");
        }
        return Base64.getEncoder().encodeToString(bytes);


    }

    /**
     * 生成折线图 多条
     *
     * @return
     */
    public static JFreeChart createManyLineChart(DefaultCategoryDataset dataSet, String title, String xtitle, String ytitle) {
        //如果把createLineChart改为createLineChart3D就变为了3D效果的折线图
        JFreeChart chart = ChartFactory.createLineChart(title, xtitle, ytitle, dataSet,
                PlotOrientation.VERTICAL, // 绘制方向
                true, // 显示图例
                true, // 采用标准生成器
                false // 是否生成超链接
        );
        //如 果不使用Font,中文将显示不出来
        Font font = new Font("新宋体", Font.BOLD, 18);

        chart.getTitle().setFont(font); // 设置标题字体
        chart.getLegend().setItemFont(font);// 设置图例类别字体
        // chart.setBackgroundPaint();// 设置背景色
        //获取绘图区对象
        CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(Color.LIGHT_GRAY); // 设置绘图区背景色
        plot.setRangeGridlinePaint(Color.gray); // 设置水平方向背景线颜色
        // 设置背景透明度
        plot.setBackgroundAlpha(0.1f);
        // 设置网格横线颜色
        plot.setRangeGridlinePaint(Color.gray);
        // 设置网格横线大小
        plot.setDomainGridlineStroke(new BasicStroke(0.2F));
        plot.setRangeGridlineStroke(new BasicStroke(0.2F));
        plot.setRangeGridlinesVisible(true);// 设置是否显示水平方向背景线,默认值为true
        plot.setDomainGridlinePaint(Color.WHITE); // 设置垂直方向背景线颜色
        plot.setDomainGridlinesVisible(true); // 设置是否显示垂直方向背景线,默认值为false


        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setLabelFont(font); // 设置横轴字体
        domainAxis.setTickLabelFont(font);// 设置坐标轴标尺值字体
        domainAxis.setLowerMargin(0.01);// 左边距 边框距离
        domainAxis.setUpperMargin(0.06);// 右边距 边框距离,防止最后边的一个数据靠近了坐标轴。
        domainAxis.setMaximumCategoryLabelLines(2);

        ValueAxis rangeAxis = plot.getRangeAxis();
        rangeAxis.setLabelFont(font);
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());//Y轴显示整数
        rangeAxis.setAutoRangeMinimumSize(1);   //最小跨度
        rangeAxis.setUpperMargin(0.18);//上边距,防止最大的一个数据靠近了坐标轴。
        rangeAxis.setLowerBound(0);   //最小值显示0
        rangeAxis.setAutoRange(false);   //不自动分配Y轴数据
        rangeAxis.setTickMarkStroke(new BasicStroke(1.6f));     // 设置坐标标记大小
        rangeAxis.setTickMarkPaint(Color.BLACK);     // 设置坐标标记颜色


        // 获取折线对象
        LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
        BasicStroke realLine = new BasicStroke(1.8f); // 设置实线
        // 设置虚线
        float dashes[] = {5.0f};
        BasicStroke brokenLine = new BasicStroke(2.2f, // 线条粗细
                BasicStroke.CAP_ROUND, // 端点风格
                BasicStroke.JOIN_ROUND, // 折点风格
                8f, dashes, 0.6f);
        for (int i = 0; i < dataSet.getRowCount(); i++) {
            if (i % 2 == 0) {
                renderer.setSeriesStroke(i, realLine); // 利用实线绘制
            } else {
                renderer.setSeriesStroke(i, brokenLine); // 利用虚线绘制
            }
            // 生成折线图上的数字
            //绘图区域(红色矩形框的部分)
            renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
            //设置图表上的数字可见
            renderer.setBaseItemLabelsVisible(true);
            //设置图表上的数字字体
            renderer.setBaseItemLabelFont(new Font("宋体", Font.BOLD, 15));

            //设置折线图拐角上的正方形
            //创建一个正方形
            Rectangle shape = new Rectangle(4, 4);
            renderer.setSeriesShape(0, shape);
            //设置拐角上图形可见
            renderer.setSeriesShapesVisible(0, true);
        }

        plot.setNoDataMessage("无对应的数据，请重新查询。");
        plot.setNoDataMessageFont(font);//字体的大小
        plot.setNoDataMessagePaint(Color.RED);//字体颜色
        return chart;

    }


}