浏览代码

Merge branch 'participle' into test

luolei 5 年之前
父节点
当前提交
822cd9e5a7
共有 9 个文件被更改,包括 371 次插入41 次删除
  1. 1 0
      package.json
  2. 83 0
      src/css/common.css
  3. 96 11
      src/css/participle.less
  4. 32 13
      src/html/participle.html
  5. 1 0
      src/js/api.js
  6. 158 17
      src/js/participle.js
  7. 二进制
      src/resources/images/iconClose3.png
  8. 二进制
      src/resources/images/iconDown.png
  9. 二进制
      src/resources/images/iconUp.png

+ 1 - 0
package.json

@@ -7,6 +7,7 @@
     "bluebird": "^3.5.5",
     "es3ify-loader": "^0.2.0",
     "jquery": "^1.12.4",
+    "poplar-annotation": "^2.0.3",
     "webpack-cli": "^3.3.1"
   },
   "devDependencies": {

+ 83 - 0
src/css/common.css

@@ -25,4 +25,87 @@ ul,li{
 }
 table,tr,td{
     list-style: none;
+}
+
+.pop-box{
+    position: absolute;
+    display: none;
+    width: 400px;
+    height: 764px;
+    background: #fff;
+    top:44px;
+    right: 0;
+    z-index: 999;
+    box-shadow:0px 14px 22px -6px rgba(20,39,75,0.12);
+    border:1px solid rgba(90,142,238,1);
+}
+.pop-box .pop-cover{
+    width: 100%;
+    height: 100%;
+    background: #000;
+    opacity: .4;
+}
+
+.pop-box .pop-container{
+    width: 400px;
+    height: 729px;
+    
+    border-radius: 5px;
+    position: absolute;
+    left: 0;
+    top:0px;
+    z-index: 2;
+}
+.pop-box .pop-title{
+    /* background: #5A8EEE; */
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px;
+    height: 35px;
+    line-height: 35px;
+    color:#fff;
+    position: absolute;
+    top: 0;
+    width: 100%;
+}
+.pop-box .pop-title h3{
+    float: left;
+    font-size: 16px;
+    text-indent: 15px;
+}
+.pop-box .pop-title .pop-close{
+    float: right;
+    margin: 7px 10px 0 0;
+    cursor: pointer;
+    width: 20px;
+}
+.pop-box .pop-ok,.pop-box .pop-cancel{
+    display: inline-block;
+    border: 1px solid #5A8EEE;
+    padding: 9px 20px;
+    text-align: center;
+    border-radius: 4px;
+    font-size: 14px;
+    cursor: pointer;
+}
+.pop-box .pop-body{
+    position: relative;
+    height: 100%;
+    margin-bottom: 20px;
+    overflow-y: auto;
+    top: 35px;
+    
+}
+.pop-box .pop-footer{
+    padding: 15px;
+    text-align: center;
+}
+.pop-box .pop-ok{
+    background-color: #5A8EEE;
+    color: #fff;
+}
+.pop-box .pop-cancel{
+    border-color: #5A8EEE;
+    color: #5A8EEE;
+    background: #fff;
+    margin: 0 0 0 50px;
 }

+ 96 - 11
src/css/participle.less

@@ -47,6 +47,7 @@
             padding: 0 20px;
             background: #fff;
             margin: 0 0 10px 0;
+            position: relative;
         }
         .infoBox{
             display: block;
@@ -105,23 +106,23 @@
             display: inline-block;
             cursor: pointer;
         }
-        .example{
-            border-color: #5A8EEE;
-            border: 1px solid #5A8EEE;
+        .example-btn{
             color: #5A8EEE;
-            padding: 9px 20px;
             text-align: center;
             border-radius:4px;
-            font-size: 14px;
+            font-size: 16px;
+            font-weight: 500;
             display: inline-block;
-            margin: 0 10px 0 0;
+            margin: 0 20px 0 0;
             cursor: pointer;
+            position: absolute;
+            right: 0;
         }
-        .example:hover{
-            background-color: #5A8EEE;
-            border-color: #5A8EEE;
-            color: #fff;
-        }
+        // .example-btn:hover{
+        //     background-color: #5A8EEE;
+        //     border-color: #5A8EEE;
+        //     color: #fff;
+        // }
         .resultBox{
             white-space: pre-wrap;
             min-height: 155px;
@@ -232,6 +233,7 @@
         }
         .empty{
             position: absolute;
+            display: none;
             width: 120px;
             height: 140px;
             top: 50%;
@@ -254,3 +256,86 @@
     }
 
 }
+.example{
+    height: 48px;
+    position: relative;
+    line-height: 48px;
+    text-indent: 15px;
+    cursor: pointer;
+    color: #000;
+    font-size: 14px;
+    &:hover,&.selected{
+        background: #F0F5FF;
+        
+    }
+}
+.exampleInfo{
+    background: #F0F5FF;
+    padding: 15px;
+    font-size: 14px;
+    line-height: 21px;
+    display: none;
+}
+.exampleBtn{
+    display: inline-block;
+    width:60px;
+    height:28px;
+    line-height: 28px;
+    border-radius:14px;
+    border:1px solid #5A8EEE;
+    color: #5A8EEE;
+    position: absolute;
+    right: 75px;
+    top: 9px;
+}
+.iconSlide{
+    position: absolute;
+    width: 14px;
+    top: 20px;
+    right: 15px;
+}
+
+
+#svg > svg {
+    width: 100%;
+}
+
+#svg .poplar-annotation-content {
+    // font-family: "PingFang SC", serif;
+    font-size: 16px;
+}
+/* Label */
+#svg .poplar-annotation-label {
+    // font-family: "PingFang SC", serif;
+    font-size: 12px;
+}
+#svg .poplar-annotation-label rect{
+    rx: 4px;
+    fill: #d8e5ff;
+    color: #cbddff;
+}
+#svg .poplar-annotation-label g rect{
+    rx: 4px;
+    fill: #d8e5ff;
+    stroke: #fff;
+}
+#svg .poplar-annotation-label.hover {
+    
+}
+#svg .poplar-annotation-label.hover rect{
+    fill: #93b6f9;
+}
+/* Connection */
+#svg .poplar-annotation-connection {
+    // font-family: "PingFang SC", serif;
+    font-size: 11px;
+}
+/* 例如根元素的id是example时,需要 */
+/* 单独的.poplar-annotation-connection-line不会生效 */
+#svg .poplar-annotation-connection-line {
+    stroke: #FEAC41;
+}
+
+#svg .poplar-annotation-connection-line.hover {
+    stroke: #5A8EEE;
+}

+ 32 - 13
src/html/participle.html

@@ -16,11 +16,26 @@
 		</div>
 		<div class="content">
 			<div class="contentInfoBox">
-				<p class="contentTitle">病历(现病史)</p>
+				<p class="contentTitle">病历(现病史)<span class="example-btn" id="showEgBtn">引用示例</span></p>
+				<div class="exampleList pop-box">
+					<!-- <div class="pop-cover"></div> -->
+					<div class="pop-container">
+						<div class="pop-title">
+							<h3>示例列表</h3>
+							<img class="pop-close" src="./images/iconClose3.png" alt="">
+						</div>
+						<div class="pop-body"></div>
+						<!-- <div class="pop-footer">
+							<button class="pop-ok">确定</button>
+							<button class="pop-cancel">取消</button>
+						</div> -->
+					</div>
+				</div>
 				<div class="infoBox">
 					<textarea name="" id="infoTxt" class="infoTxt" cols="30" rows="10" placeholder="请输入病例内容......"></textarea>
 				</div>
 				<div class="btnBox clearfix">
+					
 					<span class="btn" id="analy">开始分析</span>
 				</div>
 			</div>
@@ -31,7 +46,7 @@
 						<img class="emptyImg" src="./images/empty2.png" alt="您提交的信息暂未收录">
 						<p class="emptyTxt">暂无实体抽取数据~</p>
 					</div>
-					<div class="resultBoxInfo"></div>
+					<div class="resultBoxInfo" id="svg"></div>
 				</div>
 			</div>
 			<div class="contentInfoBox">
@@ -42,22 +57,26 @@
 						<p class="emptyTxt">暂无实体抽取数据~</p>
 					</div>
 					<p class="tableTitle">关系列表</p>
-					<table>
-						<thead>
-							<tr>
-								<td class="entry1">实体1</td>
-								<td class="relationType">关系类别</td>
-								<td class="entry2">实体2</td>
-							</tr>
-						</thead>
-						<tbody class="relationBody"></tbody>
-					</table>
+					<div class="tableWrapper">
+						<p class="analying" style="color: #aaa;text-align: center;margin-top:50px;">正在分析...</p>
+						<table>
+							<thead>
+								<tr>
+									<td class="entry1">实体1</td>
+									<td class="relationType">关系类别</td>
+									<td class="entry2">实体2</td>
+								</tr>
+							</thead>
+							<tbody class="relationBody"></tbody>
+						</table>
+					</div>
+					
 				</div>
 				
 			</div>
 		</div>
-
 	</div>
+	
 
 </body>
 

+ 1 - 0
src/js/api.js

@@ -5,6 +5,7 @@ const api = {
   getSchema:'/api/ltkg/kg/getSchema',
   getTree:'/api/ltkg/kg/getTree',
   entity_predict:'api/ltkg/nlp/getNlp',
+  getMrInfo:'/api/ltkg/presetInfo/getMrInfo',
 };
 
 const getUrlArgObject = function(name) {//

+ 158 - 17
src/js/participle.js

@@ -4,22 +4,66 @@ require("./../css/participle.less");
 require("./../css/common.css");
 const { post, api } = require('./api.js');
 require('./../resources/images/empty2.png');
+require('./../resources/images/iconUp.png');
+require('./../resources/images/iconDown.png');
+require('./../resources/images/iconClose3.png');
 const {currentIIData} = require('./data.js')
-const initData = currentIIData[14]
 
-for(let i = 0; i < 3; i++){
-    let str = `<span class="example" id="example${i+1}" data-index=${i}>示例${i+1}</span>`
-    $('.btnBox').append(str)
+function appendCurrentII(currentIIList){
+    for(let i = 0; i < currentIIList.length; i++){
+        let str = `<p class="example" id="example${i+1}" data-index=${i}>${currentIIList[i].title} <span class="exampleBtn">引用</span> <img class="iconSlide" src="./images/iconDown.png" alt="logo"></p>
+                    <div class="exampleInfo${i} exampleInfo">${currentIIList[i].content}</div>`;
+        $('.exampleList .pop-body').append(str)
+    }
+    
+    $('.example').click(function(){
+        const index1 = $(".example.selected").attr('data-index');
+        $(`.example.selected img`).attr('src','./images/iconDown.png')
+        $(`.exampleInfo${index1}`).slideUp()
+        $(".example").removeClass("selected");
+        $(this).addClass("selected");
+        const index2 = $(".example.selected").attr('data-index');
+        if($(`.exampleInfo${index2}`).css('display') === 'block'){
+            $(`.example.selected img`).attr('src','./images/iconDown.png')
+
+            $(".example").removeClass("selected");
+            $(`.exampleInfo${index2}`).slideUp()
+
+        }else{
+            $(`.exampleInfo${index2}`).slideDown()
+            $(`.example.selected img`).attr('src','./images/iconUp.png')
+        }
+        
+    });
+    $('.exampleBtn').click(function(e){
+        e.stopPropagation();
+        const index = $(this).parent().attr('data-index');
+        $('#infoTxt').val(currentIIList[index].content);
+        getEntityPredict();
+        $(".pop-box").hide();
+    });
 }
 
-$('.example').click(function(){
-    const index = $(this).attr('data-index')
-    $('#infoTxt').val(currentIIData[index])
-    getEntityPredict();
+
+
+
+
+
+$("#showEgBtn").click(function(){
+    const popShow = $(".pop-box").css('display')
+    if(popShow === 'block'){
+        $(".pop-box").hide();
+    } else{
+        $(".pop-box").show();
+    }
+    
+});
+/******弹窗事件******/
+$(".pop-cover,.pop-close,.pop-cancel").click(()=>{
+    $(".pop-box").hide();
 })
 
-$('#infoTxt').val(initData)
-getEntityPredict();
+
 function insertStr(soure, start, newStr){   
     return soure.slice(0, start) + newStr + soure.slice(start);
  }
@@ -35,20 +79,86 @@ function getEntityPredict(){
     
         ]
 
-    }
+    };
+    $(".resultBoxInfo").html(`<p style="color: #aaa;text-align: center;margin-top:50px;">正在分析...</p>`);
+    $(".analying").css('display','block');
+    $('table').css("display","none")
+    
+    $('.empty').hide();
     post(api.entity_predict, param).then(res =>{
         if(res.data.code == '0'){
             const data = JSON.parse(res.data.data)
             const result = data.data[0].entity_relation_object
-            const entryList  = result.outputs.annotation['T']
-            const relationList = result.outputs.annotation['R']
+            const entryList  = result&&result.outputs&&result.outputs.annotation['T']
+            const relationList = result&&result.outputs&&result.outputs.annotation['R']
             let content = result.content
-            getSchema(content,entryList)
-            getRelationList(relationList,entryList)
+            // getSchema(content,entryList)
+            if((JSON.stringify(entryList)!='[""]')&&(JSON.stringify(relationList)!='[""]')){
+                getRelationList(relationList,entryList)
+                let enter = chageEnter(entryList)
+                let rela = chageRelation(relationList)
+                let svgData = Object.assign(enter,rela,{"content":content})
+                showSvg(svgData)
+                $('#analy').removeClass('disabled')
+            }else{
+                $('#analy').addClass('disabled')
+                $('.resultBoxInfo').html('')
+                $('.empty').css("display","block");
+                $('.analying').css("display","none")
+                $('table').css("display","none")
+            }
         }
     })
 }
-
+function chageEnter(data){
+    var keyMap = {
+        "name" : "text",
+        "start" : "startIndex",
+        "end" : "endIndex",
+        "id" : "categoryId",
+    };
+    for(let i = 0;i < data.length;i++){
+        let obj = data[i];
+        for(let key in obj){
+            let newKey = keyMap[key];
+            if(newKey){
+                obj[newKey] = obj[key];
+                // delete obj[key];
+            }
+            obj.color = "red"
+            obj.borderColor = "#5A8EEE"
+        }
+    }
+    data.splice(0,1)
+    return {
+        "labelCategories":data,
+        "labels":data
+    }
+}
+function chageRelation(data){
+    var keyMap = {
+        "name" : "text",
+        "from" : "fromId",
+        "to" : "toId",
+        "id" : "categoryId",
+    };
+    for(let i = 0;i < data.length;i++){
+        let obj = data[i];
+        for(let key in obj){
+            let newKey = keyMap[key];
+            if(newKey){
+                obj[newKey] = obj[key];
+            }
+            obj.id = i
+            obj.categoryId = i
+        }
+    }
+    data.splice(0,1)
+    return {
+        "connectionCategories":data,
+        "connections":data,
+    }
+}
 function getSchema(content, entryList){
     let addNum = 0
     for(let i = 1; i < entryList.length; i++){
@@ -61,7 +171,6 @@ function getSchema(content, entryList){
             content = insertStr(content, entryList[i].end+addNum, '</span><span class="star">*</span>')
             addNum += 34
         }
-        
     }
     $('.resultBoxInfo').html(content)
 }
@@ -80,6 +189,7 @@ function getRelationList(relationList,entryList){
     }
     if(str){
         $('.empty').css("display","none");
+        $('.analying').css("display","none")
         $('table').css("display","table")
     }
     $('.relationBody').html(str)
@@ -91,6 +201,23 @@ $("#analy").click(function(){
         getEntityPredict()
     }
 })
+getMrInfo()
+function getMrInfo(){
+    post(api.getMrInfo, {}).then(res =>{
+        if(res.data.code == '0'){
+            const MrInfoList = res.data.data
+            const initData = MrInfoList[0].content
+            initTxtData(initData)
+            const currentIIList = MrInfoList&&MrInfoList.slice(1,MrInfoList.length)
+            appendCurrentII(currentIIList)
+        }
+    })
+}
+
+function initTxtData(data){
+    $('#infoTxt').val(data)
+    getEntityPredict();
+}
 
 $("#infoTxt").bind("input propertychange",function(event){
     const val = $("#infoTxt").val().trim()
@@ -104,3 +231,17 @@ $("#infoTxt").bind("input propertychange",function(event){
     }
 });
 
+function showSvg(data){
+    $("#svg").html("")//防止页面不渲染
+    const poplar = require('poplar-annotation');
+    const {Annotator} = poplar;
+    const elm = document.getElementById("svg");
+    new Annotator(data,elm,{
+        contentEditable:false,
+        unconnectedLineStyle:"none",
+        labelPadding:3,
+        topContextMargin:-4,
+        bracketWidth:5,
+        labelWidthCalcMethod:'label'
+    });
+}

二进制
src/resources/images/iconClose3.png


二进制
src/resources/images/iconDown.png


二进制
src/resources/images/iconUp.png