#include "plotwidget.h"
#include "xlsxdocument.h"
extern QStringList slist_temper;
extern QStringList slist_dsc;
extern QString g_sname_string;
extern double g_quality;
double g_area;
double g_kmin;
double g_b_tang1;
double g_target_x1;
double g_target_y1;
double g_kmax;
double g_b_tang2;
double g_target_x2;
double g_target_y2;


PlotWidget::PlotWidget(QWidget *parent) : QWidget(parent)
{
    qRegisterMetaType<QVariant>("QVariant");

    m_xlsx = new QXlsx::Document(this);

    m_customPlot = new QCustomPlot(this);
    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(m_customPlot);

    m_label_left = new QLabel(this);
    m_label_left->setGeometry(80, 70, 60, 20);
    m_label_left->setText(QObject::tr("左选线:"));
    m_lineEdit_left = new QLineEdit(this);
    m_lineEdit_left->setGeometry(130, 70, 60, 20);

    m_label_right = new QLabel(this);
    m_label_right->setText(QObject::tr("右选线:"));
    m_label_right->setGeometry(80, 100, 60, 20);
    m_lineEdit_right = new QLineEdit(this);
    m_lineEdit_right->setGeometry(130, 100, 60, 20);

    m_clear_button = new QPushButton(this);
    m_clear_button->setText(QObject::tr("清除曲线"));
    m_clear_button->setGeometry(80, 130, 110, 20);

    // m_save_button = new QPushButton(this);
    // m_save_button->setText(QObject::tr("保存数据"));
    // m_save_button->setGeometry(80, 152, 110, 20);

    ///m_itemLine = new QCPItemLine(m_customPlot);

    m_count_graph = 0;
    setupPlot();
    plotWaterfall();

    //建立槽函数
    connect(m_customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress(QMouseEvent*)));
    connect(m_customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMove(QMouseEvent*)));
    connect(m_customPlot, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseRelease()));
    connect(m_customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));

    connect(this, SIGNAL(send_line_data_to_plot(QVariant, QVariant)), this, SLOT(plot_connect_line(QVariant, QVariant)));
    connect(this, SIGNAL(show_min_point(double, double)), this, SLOT(show_min_point_text(double, double)));
    // connect(m_customPlot,&QCustomPlot::mouseDoubleClick,this,[=]{        //双击效果不理想
    //      m_customPlot->rescaleAxes();
    //      // m_customPlot->xAxis->rescale();
    //      // m_customPlot->yAxis->rescale();
    //      m_customPlot->replot();
    //  });

    connect(m_clear_button, SIGNAL(clicked()), this, SLOT(clear_all_graph()));
    ///connect(m_save_button, SIGNAL(clicked()), this, SLOT(save_sample_quality_area_data()));

    m_customPlot->xAxis->setRange(0, 1000, Qt::AlignCenter);
    m_customPlot->yAxis->setRange(0, 1000, Qt::AlignCenter);

    ///m_customPlot->legend->setVisible(true);
    ///m_customPlot->legend->setSelectableParts(QCPLegend::spItems);//图例本身不能被选择，只有里面的项可以被选择
    ///m_customPlot->legend->setSelectedIconBorderPen(Qt::NoPen);

}

PlotWidget::~PlotWidget()
{
    delete m_customPlot;
    delete m_label_left;
    delete m_label_right;
    delete m_lineEdit_left;
    delete m_lineEdit_right;
}

void PlotWidget::show_min_point_text(double x_min, double y_min)
{
    if(m_count_graph>0)
    {
        m_minValueText->setText(QString("峰信息:\n焓值:\n峰值:%1\n起始点:\n终止点:").arg(x_min));///.arg(y_min));
        m_minValueText->setPen(QPen(Qt::green)); //字体颜色
        m_minValueText->setColor(Qt::green);
        m_minValueText->setVisible(true);
        m_minValueText->setSelectable(true);

        ///m_minValueText->setFlag(QCPItemText::ItemIsMovable);
        ///m_minValueText->setMovable(true);
        m_minValueText->position->setCoords(x_min, y_min);
        m_customPlot->replot();
    }
}

void PlotWidget::plot_connect_line(QVariant varx, QVariant vary)
{
    if(m_count_graph>0)
    {
        QPen graphPen;
        graphPen.setColor(QColor(40, 255, 110, 250));
        graphPen.setWidthF(3.0);
        m_customPlot->addGraph();
        m_customPlot->graph()->setPen(graphPen);
        m_customPlot->graph()->setBrush(QBrush(QColor(0, 0, 255, 60)));
        ///m_customPlot->graph()->setBrush(Qt::NoBrush);

        QVector<double> vx1 = varx.value< QVector<double> >();
        QVector<double> vy1 = vary.value< QVector<double> >();

        m_count_graph++;
        m_customPlot->graph(m_count_graph)->setData(vx1, vy1);
        m_customPlot->graph(m_count_graph)->setChannelFillGraph(m_customPlot->graph(m_count_graph-1));
        m_customPlot->legend->setVisible(false);
        m_customPlot->legend->setSelectableParts(QCPLegend::spItems);
        m_customPlot->axisRect()->setupFullAxesBox(true);
        m_customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom| QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables | QCP::iMultiSelect | QCP::iSelectItems);

        m_customPlot->replot();
    }
}

void PlotWidget::save_sample_quality_area_data()
{
    m_xlsx->addSheet(g_sname_string);
    m_xlsx->setColumnWidth(1,4);//第1行,6列宽
    m_xlsx->write(1,1, g_sname_string);
    m_xlsx->write(1,2, g_quality);
    m_xlsx->write(1,3, g_area);
    m_xlsx->write(1,4, g_target_x1);
    m_xlsx->saveAs(QDir::currentPath() + "/sample.ana");
    QMessageBox::information(this,"提示","保存成功！");
}

void PlotWidget::clear_all_graph()
{
    int count=m_customPlot->graphCount();//获取曲线条数
    // for(int i=1;i<count;i++)
    // {
    //     m_customPlot->removeGraph(i);
    // }
    for(int i=count-1;i>=1;i--)
    {
         m_customPlot->removeGraph(i);
    }
    m_minValueText->setVisible(false);

    if(1==count) m_clear_button->setDisabled(true);

    m_lineLV->setVisible(false);
    m_lineRV->setVisible(false);

    m_count_graph = 0;
    m_customPlot->replot();
}

void PlotWidget::selectionChanged()
{
    // synchronize selection of graphs with selection of corresponding legend items:
    for (int i=0; i<m_customPlot->graphCount(); ++i)
    {
        QCPGraph *graph = m_customPlot->graph(i);
        QCPPlottableLegendItem *item = m_customPlot->legend->itemWithPlottable(graph);
        if (item->selected() || graph->selected())
        {
            item->setSelected(true);
            //注意：这句需要Qcustomplot2.0系列版本
            graph->setSelection(QCPDataSelection(graph->data()->dataRange()));
            //这句1.0系列版本即可
            ///graph->setSelected(true);
        }
    }
}

void PlotWidget::replot_xlsx_data()
{
    // The following plot setup is mostly taken from the plot demos:
    QPen graphPen;
    ///graphPen.setColor(QColor(std::rand()%245+10, std::rand()%245+10, std::rand()%245+10));
    graphPen.setColor(QColor(130, 40, 160));
    graphPen.setWidthF(2.0);

    m_customPlot->addGraph();
    ///m_customPlot->graph()->setPen(QPen(Qt::blue));
    m_customPlot->graph()->setPen(graphPen);
    ///m_customPlot->graph()->setBrush(QBrush(QColor(0, 0, 255, 20)));
    m_customPlot->graph()->setBrush(Qt::NoBrush);

    mutex.lock();
    if(slist_temper.size()!=slist_dsc.size()) return;
    QVector<double> x(slist_temper.size()), y0(slist_dsc.size());
    for(int i = 0; i < slist_temper.size(); ++i) {
        ///qDebug() << slist_temper.at(i).toDouble()<<Qt::endl;
        x[i] = slist_temper.at(i).toDouble();
    }
    for (int j = 0; j < slist_dsc.size(); ++j) {
        ///qDebug() << slist_dsc.at(j).toDouble()<<Qt::endl;
        y0[j] = slist_dsc.at(j).toDouble();
        ///qDebug() << y0[j] <<Qt::endl;
    }
    mutex.unlock();

    m_count_graph++;

    m_customPlot->graph(m_count_graph)->setData(x, y0);
    m_customPlot->graph(m_count_graph)->rescaleAxes();   //适应图形比例
    ///m_customPlot->graph(3)->setData(x, y1);
    m_customPlot->axisRect()->setupFullAxesBox(true);
    m_customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom| QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables | QCP::iMultiSelect | QCP::iSelectItems);
    m_customPlot->replot();

    m_clear_button->setDisabled(false);
    emit calcu_button_enable();
}

void PlotWidget::setupPlot()
{
    m_minValueText = new QCPItemText(m_customPlot);
    ///minValueText->setLayer("overlay");
    m_minValueText->setText("峰值");
    m_minValueText->setVisible(false);
    m_minValueText->setSelectable(true);

    ///m_minValueText->position->setCoords( , );

    m_tracer = new QCPItemTracer(m_customPlot);    //初始化锚点
    m_tracer->setInterpolating(false);
    m_tracer->setStyle(QCPItemTracer::tsCircle);
    m_tracer->setPen(QPen(Qt::red));
    m_tracer->setBrush(Qt::red);
    m_tracer->setSize(6);
    m_tracer->setVisible(false);


    // The following plot setup is mostly taken from the plot demos:
    m_customPlot->addGraph();
    m_customPlot->graph()->setPen(QPen(Qt::green));
    m_customPlot->graph()->setBrush(QBrush(QColor(0, 0, 255, 20)));

    QVector<double> x(500), y0(500), y1(500);

    for (int i=0; i<500; ++i)
    {
        x[i] = (i/499.0-0.5)*1000;
        y0[i] = qExp(-x[i]*x[i]*0.25)*qSin(x[i]*5)*50;
        y1[i] = qExp(-x[i]*x[i]*0.25)*50;
    }

    m_customPlot->graph(0)->setData(x, y0);
    m_customPlot->legend->setVisible(false);
    m_customPlot->legend->setSelectableParts(QCPLegend::spItems);
    m_customPlot->axisRect()->setupFullAxesBox(true);
    m_customPlot->xAxis->setLabel("Temp");
    m_customPlot->yAxis->setLabel("DSC");
    m_customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);//x轴终点箭头图案
    m_customPlot->xAxis->setLowerEnding(QCPLineEnding::esDisc);      //x轴起点圆点图案
    m_customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);//y轴终点小方块图案
    m_customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom| QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables | QCP::iMultiSelect | QCP::iSelectItems);

    ///m_customPlot->clearGraphs();
    for (int i=0; i< m_customPlot->graphCount(); ++i)
    {
        QCPGraph *graphItem = m_customPlot->graph(i);

        ///if (graphItem->selected())
        ///{
        graphItem->setVisible(false);
        ///}
    }

    m_customPlot->replot();
}

void PlotWidget::show_line_cursor()
{
    m_lineLV->setVisible(true);
    m_lineRV->setVisible(true);
    m_customPlot->replot();
}

void PlotWidget::hide_line_cursor()
{
    m_lineLV->setVisible(false);
    m_lineRV->setVisible(false);
    m_customPlot->replot();
}
/*******************
 * @author xxx
 * @method
 * @param
 * 初始化游标
*******************/
void PlotWidget::plotWaterfall()
{
    try {
        //默认曲线选择
        ///graph = customPlot->graph(0);
        ///graph = ui->plot->graph();

        //设置游标初始位置（可以不设置）
        ///QCPRange keyRange = customPlot->axisRect()->axis(QCPAxis::atBottom)->range();
        QCPRange keyRange = m_customPlot->axisRect()->axis(QCPAxis::atBottom)->range();
        // xValue1 = keyRange.upper * 0.2;
        // xValue2 = keyRange.upper * 0.7;
        xValue1 = keyRange.upper * 80;
        xValue2 = keyRange.upper * 102;
        QCPRange keyRange2 = m_customPlot->axisRect()->axis(QCPAxis::atLeft)->range();
        yValue = keyRange2.lower;
        auto iter1 = m_customPlot->graph()->data()->findBegin(xValue1);
        xValue1 = iter1->mainKey();
        auto iter2 = m_customPlot->graph()->data()->findBegin(xValue2);
        xValue2 = iter2->mainKey();

        //左游标
        QPen pen(Qt::red,1.5,Qt::SolidLine); //颜色 、宽度、样式（直线）
        m_lineLV = new QCPItemStraightLine(m_customPlot);
        m_lineLV->setLayer("overlay");
        m_lineLV->setPen(pen);//设置游标线的样式
        m_lineLV->setClipToAxisRect(true);//自适应范围
        m_lineLV->point1->setCoords(xValue1, keyRange.upper);//起点坐标
        ///m_lineLV->point2->setCoords(xValue1, 1);//终点坐标
        m_lineLV->point2->setCoords(xValue1, 1);//终点坐标
        m_lineLV->setVisible(false);

        //右游标
        ///QPen penr(Qt::green,1.5,Qt::SolidLine); //颜色 、宽度、样式（直线）
        m_lineRV = new QCPItemStraightLine(m_customPlot);
        m_lineRV->setLayer("overlay");
        m_lineRV->setPen(pen);
        m_lineRV->setClipToAxisRect(true);
        m_lineRV->point1->setCoords(xValue2, keyRange.lower);
        m_lineRV->point2->setCoords(xValue2, 1);
        m_lineRV->setVisible(false);

        //编辑框显示初始位置
        m_lineEdit_left->setText(QString::number(m_lineLV->point1->key()));
        m_lineEdit_right->setText(QString::number(m_lineRV->point1->key()));

        m_customPlot->replot();
    } catch (...) {
        qDebug("游标初始化异常！");
    }
}

/*******************
 * @author xxx
 * @method
 * @param
 * 鼠标抓取事件 点击曲线游标显示
*******************/
void PlotWidget::mousePress(QMouseEvent *event)
{
    try {

        QCPGraph *tmGraph = m_customPlot->graph(0);
        //得到锚点的像素坐标
        QPointF temp = m_tracer->position->coords();
        //将像素点转换成qcustomplot中的坐标值，并通过setGraphKey将锚点值设为真实数据值。
        m_tracer->setGraphKey(m_customPlot->xAxis->pixelToCoord(event->pos().x()));
        //遍历曲线
        for (int i = 0; i < m_customPlot->graphCount(); ++i)
        {
            //判断哪一条曲线被选中
            if(m_customPlot->graph(i)->selected())
            {
                //显示锚点
                m_tracer->setVisible(true);
                tmGraph = m_customPlot->graph(i);
                //显示tip框
                ///QToolTip::showText(event->globalPos(), tr( "<h4>%L1</h4>"
                ///QToolTip::showText(QCursor::pos(), tr( "<h4>%L1</h4>"
                QToolTip::showText(QCursor::pos(), tr("<table>"
                                                          "<tr>"
                                                          "<td><h5>X: %L1</h5></td>" "<td>  ,  </td>" "<td><h5>Y: %L2</h5></td>"
                                                          "</tr>"
                                                          "</table>").
                                                       arg( QString::number( temp.x(), 'g' ) )
                                                           .arg( QString::number( temp.y(), 'g' ) ),
                                   this, this->rect());
                break;
            }
            else
            {
                //没有曲线被选中，不显示锚点
                m_tracer->setVisible(false);
            }
        }
        //将锚点设置到被选中的曲线上
        m_tracer->setGraph(tmGraph);
        //重绘
        m_customPlot->replot();

        //定义鼠标距离游标的像素距离
        double distanceLV = m_lineLV->selectTest(event->pos(), false);
        double distanceRV = m_lineRV->selectTest(event->pos(), false);
        ///double distanceH  = m_lineH->selectTest(event->pos(), false);

        //定义游标标识，由上面的距离来决定移动那根游标
        if (event->button() == Qt::RightButton && distanceLV <= 5 && m_customPlot->axisRect()->rect().contains(event->pos())){
            lLineV = true;
        }
        if (event->button() == Qt::RightButton && distanceRV <= 5 && m_customPlot->axisRect()->rect().contains(event->pos())){
            rLineV = true;
        }

        //左右游标重合时，先移动右游标（非必须）
        if(event->button() == Qt::RightButton){//鼠标右键判断
            if(m_customPlot->axisRect()->rect().contains(event->pos())){//鼠标点在图像内
                if(distanceLV <= 5 && distanceRV <= 5){//重合时
                    //这里获取曲线的最后一个值，以判断重合位置是否在末尾，如果是则先移动左游标，否则都先移动右游标
                    ///double end = tempXpoinLists[subscript].last();
                    double end = m_lineRV->point1->key();
                    double now = m_lineLV->point1->key();
                    if(now == end){
                        lLineV = true;
                        rLineV = false;
                    }else{
                        lLineV = false;
                        rLineV = true;
                    }
                }
            }
        }
        m_customPlot->replot();
    } catch (...) {
        qDebug("系统发异常！");
    }
}
/*******************
 * @author xxx
 * @method
 * @param
 * 游标移动
*******************/
void PlotWidget::mouseMove(QMouseEvent *event)
{
    try{


        //当前鼠标位置（像素坐标）
        double x_pos = event->pos().x();
        ///double y_pos = event->pos().y();

        //像素坐标转成实际的x,y轴的坐标
        double x_val = m_customPlot->xAxis->pixelToCoord(x_pos);
        ///double y_val = m_customPlot->yAxis->pixelToCoord(y_pos);

        //获取当前曲线上最近的X轴点坐标
        if(m_count_graph<=1)
        {
            auto iter = m_customPlot->graph(m_count_graph)->data()->findBegin(x_val);
            x_val = iter->mainKey();
        }
        if(m_count_graph>1)
        {
            auto iter = m_customPlot->graph(1)->data()->findBegin(x_val);
            x_val = iter->mainKey();
        }
        //获取当前游标X轴的坐标
        double r_point = m_lineRV->point1->key();
        double l_point = m_lineLV->point1->key();
        //获取距离
        double distanceLV = m_lineLV->selectTest(event->pos(), false);
        double distanceRV = m_lineRV->selectTest(event->pos(), false);

        //当鼠标在游标上时改变鼠标形状
        if (distanceLV <= 5 || distanceRV <= 5){// || distanceH <= 5 && ui->plot->axisRect()->rect().contains(event->pos())){
            m_customPlot->setCursor(Qt::ClosedHandCursor);
        }else{
            m_customPlot->setCursor(Qt::ArrowCursor);
        }

        //游标移动判断
        if(lLineV)
        {//移动左游标
            if(x_val > r_point){ //跟右游标左判断，限制边界
                m_lineLV->point1->setCoords(r_point, m_customPlot->yAxis->range().lower);
                m_lineLV->point2->setCoords(r_point, m_customPlot->yAxis->range().upper);
            }else {
                m_lineLV->point1->setCoords(x_val, m_customPlot->yAxis->range().lower);
                m_lineLV->point2->setCoords(x_val, m_customPlot->yAxis->range().upper);
            }
            m_lineEdit_left->setText(QString::number(m_lineLV->point1->key()));
            m_customPlot->replot();
        }
        if(rLineV)
        {
            if (x_val < l_point) {
                m_lineRV->point1->setCoords(l_point, m_customPlot->yAxis->range().lower);
                m_lineRV->point2->setCoords(l_point, m_customPlot->yAxis->range().upper);
            }
            else {
                m_lineRV->point1->setCoords(x_val, m_customPlot->yAxis->range().lower);
                m_lineRV->point2->setCoords(x_val, m_customPlot->yAxis->range().upper);
            }
            m_lineEdit_right->setText(QString::number(m_lineRV->point1->key()));
            m_customPlot->replot();
        }
        //进行相应的计算
        if(lLineV || rLineV || bLineH){
            // calculate_integral();
            // calculate_average();
        }
    } catch (...) {
        qDebug("系统发异常！");
    }

}
/**
 * @brief Average::mouseRelease
 * @param e
 * 鼠标释放事件 关闭游标移动
 */
void PlotWidget::mouseRelease()
{
    lLineV = false;
    rLineV = false;
    bLineH = false;
}

void PlotWidget::get_coordinate_calcu()
{
    mutex.lock();
    if(slist_temper.size()!=slist_dsc.size()) return;
    QMap<double, double> dd_map;
    QVector<double> x(slist_temper.size()), y0(slist_dsc.size());
    for(int i = 0; i < slist_temper.size(); ++i) {
        ///qDebug() << slist_temper.at(i).toDouble()<<Qt::endl;
        x[i] = slist_temper.at(i).toDouble();
    }
    for (int j = 0; j < slist_dsc.size(); ++j) {
        ///qDebug() << slist_dsc.at(j).toDouble()<<Qt::endl;
        y0[j] = slist_dsc.at(j).toDouble();
    }
    for (int t = 0; t < slist_dsc.size(); ++t) {
        ///qDebug() << slist_dsc.at(j).toDouble()<<Qt::endl;
        dd_map.insert(x[t], y0[t]);
    }
    ///slist_temper.clear();
    ///slist_dsc.clear();
    mutex.unlock();

    double x1 = m_lineLV->point1->key();         //左选线横轴坐标值
    double x2 = m_lineRV->point1->key();         //右选线横轴坐标值
    double y1 = dd_map.value(x1);
    double y2 = dd_map.value(x2);
    double k = (y2-y1)*1.0/(x2-x1);
    double b = y1-k*x1;

    //1、获取两游标当前的坐标点
    int begin = 0, end = 0;
    double r_point = m_lineRV->point1->key();
    double l_point = m_lineLV->point1->key();
    //2、根据坐标点找到曲线中对应的数据点位置  begin是曲线中第一个点位置  end是最后一个点位置
    for (int i = 0; i < x.length(); ++i) {
        if(x[i] == l_point){
            begin = i;
        }
        if(x[i] == r_point){
            end = i;
            break;
        }
    }

    int n = end-begin+1;
    QVector<double> x_1(n), y_1(n);
    for (int i = 0; i < n; i++) {
        x_1[i] = x[begin+i];
        y_1[i] = k*x[begin+i]+b;
    }
    QVariant dataVarx,dataVary;
    dataVarx.setValue(x_1);
    dataVary.setValue(y_1);

    emit send_line_data_to_plot(dataVarx,dataVary);


    //采用的是梯形计算法，也可以采用积分等面积算法进行计算
    //根据这两个点位置区间计算所有的形成梯形面积  面积公式:（上底 + 下底）* 高 / 2;
    double upper; //上底
    double lower; //下底
    double high;  //高
    double area = 0;  //面积
    for (int i = begin; i < end; ++i) {
        upper = k*x[i]+b-y0[i];
        lower = k*x[i+1]+b-y0[i+1];
        high = x[i+1] - x[i];
        area += (upper+ lower)*high / 2;
    }
    qDebug() << "caculate area"<< area <<Qt::endl;
    g_area = area;


    //求解切线,由最低点分两段计算
    double ymin=100.0;
    int middle = 0;
    for (int j = begin; j < end-1; j++)
    {
        if(y0[j]<ymin)
        {
            ymin = y0[j];
            middle = j;
        }
    }
    emit show_min_point(x[middle], y0[middle]);
    ///QMap<double, double> qm_kb;
    double k1;
    double b1;
    double kmin = 0.0;
    double kmax = -10000.0;
    double b_tang1 = 0.0;
    int tangp1 = 0, tangp2 = 0;
    for (int j = begin+4; j < middle-4; j++)
    {
        k1= (y0[j+4]-y0[j-4])/(x[j+4]-x[j-4]);
        b1 =y0[j]-k1*x[j];
        if(k1 < kmin)
        {
            kmin = k1;
            tangp1 = j;
            b_tang1 = b1;
        }
    }

    g_kmin = kmin;
    g_b_tang1 = b_tang1;
    ///emit show_tang();
    QString expression1 = QString("y=%1 * x + %2").arg(kmin).arg(b_tang1);
    qDebug()<<"切线表达式1: "<<expression1;
    qDebug()<<"左切点坐标: "<<x[tangp1] <<","<< y0[tangp1]<<Qt::endl;
    double x_tang_1 = x[tangp1];
    double y_tang_1 = y0[tangp1];
    double x_tang_2 = m_lineLV->point1->key();
    double y_tang_2 = kmin*x_tang_2+b_tang1;

    double x_conn_3 = m_lineLV->point1->key();         //左选线横轴坐标值
    double y_conn_3 = dd_map.value(x1);
    double x_conn_4 = m_lineRV->point1->key();         //右选线横轴坐标值
    double y_conn_4 = dd_map.value(x2);

    ///Point p1,p2,p3,p4;对应的四个点，根据实际应用场景赋值
    double a1, a2, a3, c1, c2, c3;
    double t, target_x, target_y;
    a1 = y_conn_4 - y_conn_3;
    a2 = y_conn_3 - y_tang_1;
    a3 = y_tang_2 - y_tang_1;
    c1 = x_conn_4 - x_conn_3;
    c2 = x_conn_3 - x_tang_1;
    c3 = x_tang_2 - x_tang_1;
    t = (a3 * c2 - a2 * c3) / (a1 * c3 - a3 * c1);
    target_x = (x_conn_4 - x_conn_3) * t + x_conn_3;
    target_y = (y_conn_4- y_conn_3) * t + y_conn_3;

    g_target_x1 = target_x;
    g_target_y1 = target_y;

    qDebug()<<"两直线交点坐标1: "<<target_x <<","<< target_y<<Qt::endl;

    double k2;
    double b2;
    double b_tang2=0.0;
    for (int t = middle; t < end-1; t++)
    {
        k2= (y0[t+1]-y0[t-1])/(x[t+1]-x[t-1]);
        b2 =y0[t]-k2*x[t];
        if(k2 > kmax)
        {
            kmax = k2;
            tangp2 = t;
            b_tang2 = b2;
        }
    }

    g_kmax = kmax;
    g_b_tang2 = b_tang2;

    double x_tang_11 = x[tangp2];
    double y_tang_11 = y0[tangp2];
    double x_tang_22 = m_lineRV->point1->key();
    double y_tang_22 = kmax*x_tang_22+b_tang2;

    double x_conn_33 = m_lineLV->point1->key();         //左选线横轴坐标值
    double y_conn_33 = dd_map.value(x1);
    double x_conn_44 = m_lineRV->point1->key();         //右选线横轴坐标值
    double y_conn_44 = dd_map.value(x2);

    ///Point p1,p2,p3,p4;对应的四个点，根据实际应用场景赋值
    double a11, a22, a33, c11, c22, c33;
    double t2, target_x2, target_y2;
    a11 = y_conn_44 - y_conn_33;
    a22 = y_conn_33 - y_tang_11;
    a33 = y_tang_22 - y_tang_11;
    c11 = x_conn_44 - x_conn_33;
    c22 = x_conn_33 - x_tang_11;
    c33 = x_tang_22 - x_tang_11;
    t2 = (a33 * c22 - a22 * c33) / (a11 * c33 - a33 * c11);
    target_x2 = (x_conn_44 - x_conn_33) * t2 + x_conn_33;
    target_y2 = (y_conn_44- y_conn_33) * t2 + y_conn_33;

    g_target_x2 = target_x2;
    g_target_y2 = target_y2;

    qDebug()<<"两直线交点坐标2: "<<target_x2 <<","<< target_y2<<Qt::endl;
    emit show_area();
    emit show_tang();
    ///emit show_connect_line(x1, y1, x2, y2);

    QString expression2 = QString("y=%1 * x + %2").arg(kmax).arg(b_tang2);
    qDebug()<<"切线表达式2: "<<expression2;

    qDebug() << "begin"<< begin << "middle"<< middle << "end"<< end <<Qt::endl;

}





