最近为一家企业做一个网站系统,涉及到一些指标公式的制定和显示问题。其中指标公式的制定包括:直线方程式、多项式方程式以及由这两种方程式组合的分段函数。经过讨论,方案如下:
1、使用适合的数据结构进行相关字段的存储和解析:x的区间、直线的斜率和偏置、多项式的系数等。
2、后台使用python进行相关字段的解析和处理。
3、前端使用js进行相关字段的解析,并使用highcharts进行显示。
1、实现了直线方程式、多项式方程式以及由这两种方程式组合的分段函数,使得用户可以根据需求,制定相关的公式。
2、通过js和bootstrap实现了较好的用户交互界面,用户可添加任意数量的直线方程式或者多项式方程式,同时还可以删除由于误操作添加的方程式。
3、实现了分段函数的显示:直线方程式 + 曲线方程式。
1、搭建【django】开发环境:http://blog.csdn.net/houchaoqun_xmu/article/details/53693347
2、下载【highcharts】插件:https://www.hcharts.cn/demo/highcharts
3、下载【jQuery】插件:http://jquery.com/download/
1、添加多项式方式的输入框,并提供删除功能,如下图所示:
2、数据结构:
一般情况:没有分段函数
=== x_Value:存储直线和多项式方程中x的区间,以下划线“_”分隔,形如:0_100表示从0到100。
=== k_Value:存储直线方程的斜率,多项式方程中带有未知数x的系数(以分号;分隔)。
=== b_Value:存储直线方程的偏置,多项式方程中不带未知数x的系数。
特殊情况:含有分段函数,直线+直线、直线+多项式、多项式+多项式
如下图所示为“直线+多项式+直线”的模式,以此为例,分析 x_Value、k_Value 和 b_Value 的取值:
=== x_Value = 0_7_28_inf,表示区间[0, 7]、[7, 28]和[28, 正无穷]
=== k_Value = 0_ 0.00346;-0.15469;-2.93331_0,以下划线_为分隔符分别表示3个曲线对应的值,第一个0对应区间[0, 7]中直线方程的斜率、0.00346;-0.15469;-2.93331对应区间[7, 28]中多项式方程未知数的系数,第二个0对应区间[28, 正无穷]中直线方程的斜率。值得一提的是,如何判别是普通直线或者多项式方程的办法就是通过分号【;】进行判断。
=== b_Value = 100_127.46927_0,对应3个区间的3个偏置项。
3、解析【x_Value】【k_Value】【b_Value】,并分别对直线方程和多项式方程进行处理:
通过函数 strip() 和 split() 将字符串通过下划线_分隔为list[ ]
X_list = x_Value.strip().split('_') K_list = k_Value.strip().split('_') B_list = b_Value.strip().split('_')根据上述的例子,处理后如下所示:
=== X_list = [u'0', u'7', u'28', u'inf']
=== K_list = [u'0', u' 0.00346;-0.15469;-2.93331', u'0']
=== B_list = [u'100', u'127.46927', u'0'] 根据 K_list[ ] 进行分段处理,K_list[i]中不存在分号【;】的就是普通直线,存在分号【;】的就是多项式方程,如下所示:
for k in K_list: # print k expression = "" if k.find(";") == -1: print "=== line ===" if K_list[i]=='0': expression = "y = " + B_list[i] elif K_list[i]=='1': if (B_list[i]).find("-") == -1: if B_list[i]==0: expression = "y = x" else: expression = "y = x + " + B_list[i] else: expression = "y = x " + B_list[i] else: if (B_list[i]).find("-") == -1: if B_list[i]==0: expression = "y = " + K_list[i] + "x" else: expression = "y = " + K_list[i] + "x + " + B_list[i] else: expression = "y = " + K_list[i] + "x " + B_list[i] else: print "=== curve ===" curve_list = k.strip().split(';') j = 0 curve_len = len(curve_list) print "curve_len = ",curve_len for j in range(curve_len): # exponent: 指数 # curve_list[j]: 系数 exponent = str(curve_len - j) print "exponent = ",exponent if curve_list[j] == "0": expression = expression elif curve_list[j] == "1": if exponent == "1": expression = expression + " + x" else: expression = expression + " + " + "x^" + exponent elif curve_list[j] == "-1": if exponent == "1": expression = expression + " - x " else: expression = expression + " - x^" + exponent # coefficient > 0 except 1 elif (curve_list[j]).find("-") == -1: if exponent == "1": # the begin position. if j == 0: expression = curve_list[j] + "x" else: expression = expression + " + " + curve_list[j] + "x" else: if j == 0: expression = curve_list[j] + "x^" + exponent else: expression = expression + " + " + curve_list[j] + "x^" + exponent # coefficient < 0 except -1 else: if exponent == "1": expression = expression + curve_list[j] + "x" else: expression = expression + curve_list[j] + "x^" + exponent if (B_list[i]).find("-") == -1: expression = "y = " + expression + " + " + B_list[i] else: expression = "y = " + expression + B_list[i] expressions_list.append(display_expression(X_list[i], X_list[i+1], expression)) i = i + 1使用类 display_expression 存储每一个区间的信息,包括区间的起始位置和表达式,如下所示:
### class ### class display_expression: def __init__(self, x_start, x_end, expression): self.x_start = x_start self.x_end = x_end self.expression = expression注:js的解析和处理思想类似。
四、实现步骤:
1、基于django,创建一个工程SettingFormula和app_SettingFormula:
python .\django-admin.py startproject SettingFormula python .\manage.py startapp app_SettingFormula2、配置settings.py:
=== 在【INSTALLED_APPS】处加入新建的app_SettingFormula
=== 配置static和templates:
STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates'), # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. )3、引入相关的.js和.css文件
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.css' %}"> <link rel="stylesheet" type="text/css" href="{% static 'css/Water.css' %}"> <script type="text/javascript" src = "{% static 'js/jquery.min.js' %}" ></script> <script type="text/javascript" src = "{% static 'js/bootstrap.js' %}" ></script> <script type="text/javascript" src = "{% static 'js/highcharts.js' %}" ></script>4、实现简单的html界面
<div style="text-align: center;"> <label style="font-size: 18px;">公式的定制:直线方程式 + 多项式方程式</label> </div> <div class="row" style="padding-top: 30px;"> <div class="col-md-3"></div> <!-- 定制指标公式 - 相关信息 --> <div class="col-md-6"> <div class="panel" style="border: 1px solid #e0e0e0;"> <div class="panel-heading"> <label>制定直线方程式和多项式方程式:</label> <button id="btn_save" class="btn btn-sm btn-success pull-right" type="button">保存设置</button> </div> <div style="text-align: center;padding: 5px 0;background-color: #f0f0f0;"> <input id="newBtn" class="btn btn-sm btn-success" type="button" value="添加直线方程"> <a class="btn btn-sm btn-success" data-toggle="modal" data-target="#Add_curve" role="button">添加多项式方程</a> </div> <div class="panel-body"> <table id="IndicatorFormula_modify"> <tr></tr> </table> </div> </div> </div> </div> <div class="row"> <div class="col-md-3"></div> <div class="col-md-6"> <div class="panel" style="border: 1px solid #e0e0e0;"> <div class="panel-heading"> <label>当前指标公式信息:</label> </div> <div class="panel-body"> <table class="" style="margin: 5px;"> {% for expression in expressions_list %} <tr style="font-size: 15px;"> <td><span class="glyphicon glyphicon-hand-right"></span> 区间:[{{ expression.x_start }} , {{ expression.x_end }}]</td> <td width="5%"></td> <td>表达式:{{expression.expression}}</td> </tr> {% endfor %} </table> </div> </div> </div> </div> <div class="row"> <div class="col-md-3"></div> <div class="col-md-6"> <div id="LineContainer_test"></div> </div> </div> <br> <div class="modal fade" id="Add_curve"> <div class="modal-dialog" style="width:300px;"> <div class="modal-content"> <div class="modal-body"> 请输入曲线最高次指数:<input type="text" id="curve_num" style="width:60px;"> <input id="newBtn_curve" class="btn-sm btn-success pull-right" type="button" value="确定"> </div> </div> </div> </div>5、使用js实现用户点击“添加直线方程”和“添加多项式方程”弹出对应的输入框:
// line $("#newBtn").bind("click", function(){ // console.log(this.id) // console.log(count); var seq = count.toString(); // console.log(seq); line_num.push(1); $str = "" $str += "<tr>"; $str += "<td>"; $str += "起始点: x_0 = <input id=\"x" + seq + "\" name=\"input_x\" type=\"text\" style=\"width: 40px;\"> "; $str += "截止点: x_1 = <input id=\"x" + seq + "\" name=\"input_x_1\" type=\"text\" style=\"width: 40px;\"> "; $str += "<td>"; $str += "直线斜率 = <input id=\"k" + seq + "\" name=\"input_k\" type=\"text\" style=\"width: 40px;\">"; $str += "</td>"; $str += "<td>"; $str += "直线偏置 = <input id=\"y" + seq + "\" name=\"input_b\" type=\"text\" style=\"width: 40px;\">"; $str += "</td>"; $str += "<td width=\"10%\"><input id=\"deleteLine_" + count + "\" class = \"btn btn-sm btn-success\" type=\"button\" value=\"删除表达式\" onClick='getDel(this)'></td>"; $str += "</tr>"; $("#IndicatorFormula_modify").append($str); count++; }); // curve $("#newBtn_curve").bind("click", function(){ var curve_num = $("#curve_num").val(); // console.log(curve_num); if(curve_num > 0){ $('#Add_curve').modal('hide'); line_num.push(parseInt(curve_num)); var count_curve = 0; var seq = count.toString(); var curve_length = curve_num; var seq_curve = count_curve.toString(); $str = "" $str += "<tr style='color:#960000;' id='curveID_0'>"; $str += "<td>"; $str += "起始点: x_0 = <input id=\"x" + seq + "\" name=\"input_x\" type=\"text\" style=\"width: 40px;\"> "; $str += "截止点: x_1 = <input id=\"x" + seq + "\" name=\"input_x_1\" type=\"text\" style=\"width: 40px;\"> "; $str += "<td>"; $str += "曲线系数 = <input id= coefficient_" + curve_length.toString() + " name=\"input_k\"" + " type=\"text\" style=\"width: 40px;\"> " + "x^" + curve_length; $str += "</td><td></td>"; $str += "<td width=\"10%\"><input id=\"deleteLine_" + count_curve + "\" class = \"btn btn-sm btn-success\" type=\"button\" value=\"删除表达式\" onClick='getDelCurve(" + curve_num.toString() + ")'></td>"; $str += "</tr>"; $("#IndicatorFormula_modify").append($str); count_curve++; for(var i = count_curve; i <= curve_length; i++){ var seq_curve = i.toString(); var curveID = 'curveID_' + i.toString(); var curve_tr_content = "style = 'color:#960000;' id = " + curveID; $str = "" $str += "<tr " + curve_tr_content + ">"; $str += "<td></td>"; $str += "<td>"; if ((curve_length - i) != 0) { $str += "曲线系数 = <input id= coefficient_" + (curve_length - i).toString() + " name=\"input_k\"" + " type=\"text\" style=\"width: 40px;\"> " + "x^" + (curve_length - i); } else { $str += "曲线偏置 = <input id=\"y" + seq + "\" name=\"input_b\" type=\"text\" style=\"width: 40px;\">"; } $str += "</td><td></td>"; $str += "<td></td>"; $str += "</tr>"; $("#IndicatorFormula_modify").append($str); } }else{ alert("请输入大于0的数值!"); } count++; });6、删除直线方程和多项式方程的输入框:
// delete line input function getDel(select_remove){ $(select_remove).parent().parent().remove(); } // delete curve input function getDelCurve(delete_num){ delete_num = parseInt(delete_num); for(var i = 0; i <= delete_num; i++){ delete_id = "curveID_" + i.toString(); console.log(delete_id); $("tr[id=" + delete_id + "]").remove(); } }7、将用户填写的数据通过post方法提交至后台:
function post(URL, PARAMS) { var temp = document.createElement("form"); temp.action = URL.toString(); temp.method = "post"; temp.style.display = "none"; for (var x in PARAMS) { var opt = document.createElement("textarea"); opt.name = x; opt.value = PARAMS[x]; console.log(opt.value); temp.appendChild(opt); } // alert("xx"); document.body.appendChild(temp); temp.submit(); return temp; } function IsNum(s) { if(s.toLowerCase() == "inf"){ return true; } if (s!=null && s!="") { return !isNaN(s); } return false; }$("#btn_save").bind("click", function(){ var x = ""; var b = ""; var k = ""; var x_list = document.getElementsByName("input_x"); var b_list = document.getElementsByName("input_b"); // y 表示偏置b var k_list = document.getElementsByName("input_k"); var x_1_list = document.getElementsByName("input_x_1"); // console.log(x_list); // console.log(b_list); // console.log(k_list); // console.log(x_1_list); for (var i = 0; i < x_list.length; ++i) { // alert("ss"); if(!IsNum(x_list[i].value) || !IsNum(b_list[i].value) || !IsNum(x_1_list[i].value)) { alert("请确认输入都为数字或者[Inf]表示无限大."); return; } if(parseFloat(x_list[i]) > 1 || parseFloat(x_list[i]) < 0) { alert(x_list[i].id + "输入不合法。"); return; } if(parseFloat(b_list[i]) > 100 || parseFloat(x_list[i]) < 0) { alert(b_list[i].id + "输入不合法。"); return; } } for (var i = 0; i < k_list.length; ++i) { if(!IsNum(k_list[i].value)) { alert("请确认输入都为数字"); return; } } var k_seq = 0; for (var i = 0; i < x_list.length; ++i) { x = x + x_list[i].value + "_"; b = b + b_list[i].value + "_"; var sub_k = ""; for (var j = 0; j < line_num[i]; ++j) { sub_k = sub_k + k_list[k_seq + j].value + ";"; // console.log("k_seq: " + k_seq + j); } k_seq = k_seq + line_num[i]; sub_k = sub_k.substring(0, sub_k.length - 1); k = k + sub_k + "_"; } x = x + x_1_list[x_1_list.length - 1].value // console.log(b_list[b_list.length - 1].value) // console.log(x_list[x_list.length - 1].value) // console.log() // console.log(b); b = b.substring(0, b.length - 1); k = k.substring(0, k.length - 1); // console.log(x); // console.log(b); // console.log(k); // console.log(typeof(k)); post("", { x_Value: x, b_Value: b, k_Value: k }); });
8、根据post传来的数据,后台使用python进行数据处理:
def get_IndicatorFormula_expression(x_Value, k_Value, b_Value): X_list = x_Value.strip().split('_') K_list = k_Value.strip().split('_') B_list = b_Value.strip().split('_') # print "---" # print "X_list",X_list # print "B_list",B_list i = 0 expressions_list = [] # line and curve # find()函数找不到时返回为-1。 for k in K_list: # print k expression = "" if k.find(";") == -1: print "=== line ===" if K_list[i]=='0': expression = "y = " + B_list[i] elif K_list[i]=='1': if (B_list[i]).find("-") == -1: if B_list[i]==0: expression = "y = x" else: expression = "y = x + " + B_list[i] else: expression = "y = x " + B_list[i] else: if (B_list[i]).find("-") == -1: if B_list[i]==0: expression = "y = " + K_list[i] + "x" else: expression = "y = " + K_list[i] + "x + " + B_list[i] else: expression = "y = " + K_list[i] + "x " + B_list[i] else: print "=== curve ===" curve_list = k.strip().split(';') j = 0 curve_len = len(curve_list) print "curve_len = ",curve_len for j in range(curve_len): # exponent: 指数 # curve_list[j]: 系数 exponent = str(curve_len - j) print "exponent = ",exponent if curve_list[j] == "0": expression = expression elif curve_list[j] == "1": if exponent == "1": expression = expression + " + x" else: expression = expression + " + " + "x^" + exponent elif curve_list[j] == "-1": if exponent == "1": expression = expression + " - x " else: expression = expression + " - x^" + exponent # coefficient > 0 except 1 elif (curve_list[j]).find("-") == -1: if exponent == "1": # the begin position. if j == 0: expression = curve_list[j] + "x" else: expression = expression + " + " + curve_list[j] + "x" else: if j == 0: expression = curve_list[j] + "x^" + exponent else: expression = expression + " + " + curve_list[j] + "x^" + exponent # coefficient < 0 except -1 else: if exponent == "1": expression = expression + curve_list[j] + "x" else: expression = expression + curve_list[j] + "x^" + exponent if (B_list[i]).find("-") == -1: expression = "y = " + expression + " + " + B_list[i] else: expression = "y = " + expression + B_list[i] expressions_list.append(display_expression(X_list[i], X_list[i+1], expression)) i = i + 1 return expressions_list9、基于highcharts绘制坐标图:
$(function () { var x = "{{ x_Value }}", b = "{{ b_Value }}", k = "{{ k_Value }}"; var i; var xValue = x.split("_"); var bValue = b.split("_"); var kValue = k.split("_"); // 未知量的系数 // console.log(xValue); // console.log(bValue); // console.log(kValue); // console.log(parseFloat(xValue[2] * kValue[1]) + parseFloat(bValue[1])); // console.log(); var data = new Array(); // 判断线段的类型: // 1、只有直线 // 2、有直线,又有曲线 var has_curve = false; // 如果包含子串,则返回大于等于0的索引,否则返回-1 for(var k = 0; k < kValue.length; k++){ if(kValue[k].indexOf(";")>=0){ has_curve = true; break; } } // has_curve == true 表示包含曲线 if(has_curve == true){ console.log("there is curve."); for(i = 0; i < bValue.length; i++){ if((xValue[i+1]) && (xValue[i+1].toLowerCase() == "inf")){ xValue[i+1] = 2 * xValue[i] + 40; } if(kValue[i].indexOf(";")>=0){ // 曲线处理 coefficient_list = kValue[i].split(";"); var y_0 = 0, y_1 = 0, y_2 = 0, y_3 = 0, y_4 = 0, y_5 = 0; for(var k = 0; k < coefficient_list.length; k++){ y_0 = y_0 + parseFloat(coefficient_list[k]) * Math.pow(xValue[i], parseInt( coefficient_list.length - k)); y_1 = y_1 + parseFloat(coefficient_list[k]) * Math.pow(parseInt(xValue[i+1]/4), parseInt( coefficient_list.length - k)); y_2 = y_2 + parseFloat(coefficient_list[k]) * Math.pow(parseInt(xValue[i+1]/2), parseInt( coefficient_list.length - k)); y_3 = y_3 + parseFloat(coefficient_list[k]) * Math.pow(parseInt(xValue[i+1]/1.5), parseInt( coefficient_list.length - k)); y_4 = y_4 + parseFloat(coefficient_list[k]) * Math.pow(parseInt(xValue[i+1]/1.2), parseInt( coefficient_list.length - k)); y_5 = y_5 + parseFloat(coefficient_list[k]) * Math.pow(xValue[i+1], parseInt( coefficient_list.length - k)); } y_0 = y_0 + parseFloat(bValue[i]); y_0 = y_0.toFixed(2); data.push([parseFloat(xValue[i]), parseFloat(y_0)]); y_1 = y_1 + parseFloat(bValue[i]); y_1 = y_1.toFixed(2); data.push([parseFloat(parseInt(xValue[i+1]/4)), parseFloat(y_1)]); y_2 = y_2 + parseFloat(bValue[i]); y_2 = y_2.toFixed(2); data.push([parseFloat(parseInt(xValue[i+1]/2)), parseFloat(y_2)]); y_3 = y_3 + parseFloat(bValue[i]); y_3 = y_3.toFixed(2); data.push([parseFloat(parseInt(xValue[i+1]/1.5)), parseFloat(y_3)]); y_4 = y_4 + parseFloat(bValue[i]); y_4 = y_4.toFixed(2); data.push([parseFloat(parseInt(xValue[i+1]/1.2)), parseFloat(y_4)]); y_5 = y_5 + parseFloat(bValue[i]); y_5 = y_5.toFixed(2); data.push([parseFloat(xValue[i+1]), parseFloat(y_5)]); } else{ // 直线处理 var y_0 = parseFloat((xValue[i]) * kValue[i]) + parseFloat(bValue[i]); y_0 = y_0.toFixed(2); data.push([parseFloat(xValue[i]), parseFloat(y_0)]); var y_1 = parseFloat((xValue[i+1]) * kValue[i]) + parseFloat(bValue[i]); y_1 = y_1.toFixed(2); data.push([parseFloat(xValue[i+1]), parseFloat(y_1)]); } } // LineContainer_test $('#LineContainer_test').highcharts({ title: { text: '' }, credits: { enabled: false }, xAxis: { minorTickInterval: 1, tickInterval: 5, }, yAxis: { title: { text: null }, tickInterval: 1 }, tooltip: { headerFormat: '<b>{series.name}</b><br />', pointFormat: 'x = {point.x}, y = {point.y}' }, series: [{ name: '标准化得分', data: data, type: 'spline', }] }); }else{ console.log("there is only line."); for(i = 0; i < bValue.length; i++){ if((xValue[i+1]) && (xValue[i+1].toLowerCase() == "inf")){ xValue[i+1] = 2 * xValue[i] + 80; } // two points to form a line. // console.log("=================="); var y_0 = parseFloat((xValue[i]) * kValue[i]) + parseFloat(bValue[i]); y_0 = y_0.toFixed(2); data.push([parseFloat(xValue[i]), parseFloat(y_0)]); // console.log(parseFloat(xValue[i])); // console.log(parseFloat(y_0)); var y_1 = parseFloat((xValue[i+1]) * kValue[i]) + parseFloat(bValue[i]); y_1 = y_1.toFixed(2); data.push([parseFloat(xValue[i+1]), parseFloat(y_1)]); // console.log(parseFloat(xValue[i+1])); // console.log(parseFloat(y_1)); } $('#LineContainer_test').highcharts({ chart: { height:263, backgroundColor: '#f0f0f0' }, credits: { enabled: false }, title: { text: ' ' }, xAxis: { minorTickInterval: 1, tickInterval: 5, }, yAxis: { type: 'linear', minorTickInterval: 0.1, tickInterval: 5, title:{ enabled: false, text: 'y值' } }, legend: { layout: 'vertical', backgroundColor: '#f0f0f0', floating: true, align: 'left', x: 30, verticalAlign: 'top', y: 30 }, tooltip: { headerFormat: '<b>{series.name}</b><br />', pointFormat: 'x = {point.x}, y = {point.y}' }, series: [{ data, pointStart: 0, name: '指标公式图', }] }); } });1、【博客资源】http://download.csdn.net/detail/houchaoqun_xmu/9834798
2、【Github】https://github.com/Houchaoqun/Daily-Coding/tree/master/web_development/SettingFormula_django_highcharts_js
注:Github的代码最新,而且有进展会持续更新。
本文基于【django + js + highcharts】实现了普通直线方程式和曲线方程式的制定,包括:
1、用户根据自身需求添加普通直线方程式或曲线方程式,弹出对应的输入框。
2、用户根据自身需求可删除上一步添加的输入框。
3、设计相应的数据结构,根据用户所输入的方程式信息进行解析,后台使用python语言进行解析,返回对应的区间和方程式。
4、基于highcharts绘制方程式对应的坐标系,前端使用js进行解析,根据方程式的类型(普通直线或者多项式方程式)做相应的处理。
本文目前只实现了普通直线方程式和曲线方程式的处理,尚未扩展到一般的曲线,如今后有这方面的需求,实现后会再补充整理分享给大家。
值得一提的是,本文的方法目前仍存在如下缺陷:
1、对highcharts插件不够熟悉,绘制多项式曲线的时候,效果不是很好,本文采用的方法是使用【type: 'spline'】,在相应的区间内绘制多个点,构成对应的曲线,如下图所示,多项式方程式【y = 2x^3 + 0】在区间[0, 100]内,绘制了20个点构成了对应的曲线。
上图的效果还不错,但是,细心的同学可以注意到区间 [0, 25] 中,由于没有绘制多个点,导致不能更好的逼近曲线,代码中有详细解释这个问题。此外,这个方法在“仅有多项式方程式”的情况表现良好,但是,在混合方程式中的表现就不尽人意,比如“直线+多项式+直线”,如下图所示,多项式曲线部分的效果不是很好,可能是因为图不够大,但这不是能够接受的理由,后续有机会再继续完善。
2、按照如下过程会有bug:
先添加直线方程的输入框 --> 再添加曲线方程的输入框(如:最高指数幂为3) --> 删除直线方程的输入框 --> 输入曲线的相关参数(如:y = -2x^3 + x^2 -1),此时会出现问题:出来的是一条直线,因为一开始删除的直线方程输入框的原因,导致系统把当前的曲线识别为直线的输入框。
=== 解决bug: