Browse Source

医学术语关联

zhangxc 4 years ago
parent
commit
9890d8541d
8 changed files with 509 additions and 42 deletions
  1. 21 0
      src/css/common.less
  2. 170 26
      src/css/medicalTermMap.less
  3. 30 13
      src/html/medicalTermMap.html
  4. 1 0
      src/js/api.js
  5. 0 1
      src/js/graphMap.js
  6. 274 1
      src/js/medicalTermMap.js
  7. 12 0
      src/js/utils.js
  8. 1 1
      webpack.config.js

+ 21 - 0
src/css/common.less

@@ -136,4 +136,25 @@ table,tr,td{
     color: #5A8EEE;
     background: #fff;
     margin: 0 0 0 50px;
+}
+
+input:focus,textarea:focus{
+    border: 1px solid #58a6e7 !important;
+    outline: 0;
+    -webkit-box-shadow:#58a6e7 0px 0px 2px;
+    -moz-box-shadow: #58a6e7 0px 0px 2px;
+    box-shadow: #58a6e7 0px 0px 2px;
+}
+input::-webkit-input-placeholder{
+    color: #ccc;
+}
+    
+input:-moz-placeholder,textarea:-moz-placeholder{
+    color: #ccc;
+}
+input::-moz-placeholder,textarea::-moz-placeholder{
+    color: #ccc;
+}
+input:-ms-input-placeholder,textarea:-ms-input-placeholder{
+    color: #ccc;
 }

+ 170 - 26
src/css/medicalTermMap.less

@@ -1,6 +1,7 @@
-.knowledgeMapWrapper{
+
+.knowledgeMapWrapper {
     min-width: 1200px;
-  /* .title{
+    /* .title{
         position: relative;
         height: 40px;
         line-height: 40px;
@@ -34,28 +35,171 @@
         height: 40px;
         line-height: 40px;
     }*/
-   .content{
-       position: relative;
-       width: 1200px;
-       left: 50%;
-       margin-left: -600px;
-       cursor: default;
-       height: 100%;
-   }
-   .bottom{
-    
-       background: #fff;
-     
-       position: relative;
-   }
-   
-  .footer{
-      position: absolute;
-      width: 100%;
-      bottom: 10px;
-      text-align: center;
-      font-size: 12px;
-      color: #ccc;
-  }
-  
+    .title{
+        position: fixed;
+        top: 0;
+        z-index: 2;
+    }
+    .content {
+        position: relative;
+        width: 1200px;
+        left: 50%;
+        margin: 54px 0 0 -600px;
+        cursor: default;
+        height: 100%;
+        font-size: 14px;
+    }
+
+    .top {
+        background: #fff;
+        position: relative;
+        margin: 10px 0;
+    }
+
+    .tabList {
+        padding: 0 20px;
+        height: 44px;
+        border-bottom: 1px solid #E6E6E6;
+        color: #777;
+    }
+
+    .tabItem {
+        display: inline-block;
+        padding: 0 15px;
+        cursor: pointer;
+        height: 32px;
+        line-height: 32px;
+        position: relative;
+        top: 12px;
+    }
+
+    .infoTxt {
+        min-height: 33px;
+        width: 1160px;
+        font-size: 14px;
+        color: #333;
+        resize: none;
+        line-height: 20px;
+        // outline: none;
+        padding: 10px;
+        background: #F7F8FA;
+        border: 1px solid #ccc;
+        box-sizing: border-box;
+        margin: 20px;
+    }
+
+    .btnBox {
+        text-align: center;
+        padding: 0 0 20px 0;
+    }
+
+    .submit {
+        display: inline-block;
+        padding: 8px 36px;
+        background: #5A8EEE;
+        color: #fff;
+        border-radius: 4px;
+        cursor: pointer;
+    }
+
+    .termResult {
+        margin: 10px 0 0 0;
+        padding: 0 0 0 20px;
+    }
+
+    .mapResultTitle,
+    .graphTitle {
+        font-size: 16px;
+        font-weight: 600;
+        color: #333;
+        line-height: 44px;
+    }
+
+    .mapResult {
+        margin: 0 0 20px 0;
+        color: #AAA;
+    }
+    .noResult{
+        color: #AAA;
+    }
+
+    .bottom {
+        margin: 0 0 10px 0;
+        background: #fff;
+        padding-bottom: 50px;
+        position: relative;
+    }
+    .graphTitle{
+        padding: 0 20px;
+        border-top: 1px solid #E6E6E6;
+    }
+    .mapWrapper{
+        position: relative;
+        top: 20px;
+        left: 50%;
+        margin-left: -398px;
+    }
+    .mainCont{
+        position: relative;
+    }
+    .emptyBox{
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        background: #fff;
+        left: 0;
+        top: 0;
+        text-align: center;
+        z-index: 2;
+        // display: none;
+        img,p{
+            position: relative;
+            top: 150px;
+        }
+        img{
+            width: 140px;
+        }
+        p{
+            color:#AAA;
+            text-indent: 10px;
+            top: 155px;
+        }
+    }
+    .footer {
+        position: absolute;
+        width: 100%;
+        bottom: 10px;
+        text-align: center;
+        font-size: 12px;
+        color: #ccc;
+    }
+
+    .disabled {
+        opacity: 0.5;
+        filter: "alpha(opacity=50)";
+        filter: alpha(opacity=50);
+        cursor: not-allowed;
+    }
+
+    .activeTab {
+        font-size: 16px;
+        color: #5A8EEE;
+        background:linear-gradient(180deg,rgba(126,171,255,1) 0%,rgba(90,142,238,1) 100%);
+        border-radius:6px 6px 0px 0px;
+        box-sizing: border-box;
+        color: #fff;
+    }
+    .resultItem{
+        cursor: pointer;
+        display: inline-block;
+        padding: 5px 13px;
+        border: 1px solid #AAA;
+        margin: 20px 20px 0 0;
+        border-radius:4px;
+    }
+    .resultActive{
+        background: #EEF4FF;
+        color: #5A8EEE;
+        border: 1px solid #5A8EEE;
+    }
 }

+ 30 - 13
src/html/medicalTermMap.html

@@ -21,23 +21,40 @@
 		</div>
 		<div class="content clearfix">
             <div class="top">
-                <div class="topLeft">
-                    <div class="tabList"></div>
-                    <textarea name="" id="" cols="30" rows="10"></textarea>
+                <div class="termInput">
+                    <ul class="tabList">
+                        <li class="tabItem activeTab" title="疾病"  data-type="disease" data-name="疾病">疾病</li>
+						<li class="tabItem" title="药品"  data-type="drug" data-name="药品通用名">药品</li>
+						<li class="tabItem" title="症状" data-type="symptom" data-name="症状">症状</li>
+						<li class="tabItem" title="手术和操作" data-type="operation" data-name="手术和操作">手术和操作</li>
+						<li class="tabItem" title="实验室检查" data-type="lis" data-name="实验室检查">实验室检查</li>
+						<li class="tabItem" title="辅助检查" data-type="pacs" data-name="辅助检查">辅助检查</li>
+                    </ul>
+                    <textarea name="" id="infoTxt" class="infoTxt" cols="30" rows="5" placeholder="请在此输入问题…"></textarea>
                 </div>
-                <div class="topRight">
-                    <p class="mapResultTitle">
-                        标准词映射结果
-                    </p>
-                    <div class="mapResult"></div>
-                </div>
-                <div>
-                    <span class="submit">提交</span>
+                <div class="btnBox">
+                    <span class="submit" id="submit">提交</span>
                 </div>
+               
             </div>
+           
 			<div class="bottom">
-                <p class="graphTitle">图谱映射结果</p>
-				<div id="main" class="mapWrapper" style="width: 796px;height:600px;cursor: pointer;"></div>
+				<div class="termResult">
+                    <p class="mapResultTitle">
+                        标准词映射结果:
+                    </p>
+                    <div class="mapResult noResult">暂无结果~</div>
+                </div>
+				<p class="graphTitle">图谱映射结果:</p>
+				
+				<div class="mainCont">
+					<div class="emptyBox">
+						<img src ='./images/empty2.png'>   
+						<p>暂无结果~</p>
+					</div>
+					<div id="main" class="mapWrapper" style="width: 796px;height:600px;cursor: pointer;"></div>
+
+				</div>
 				 <div class="footer">
 					杭州朗通信息技术有限公司 & 浙江大学医学院附属邵逸夫医院&nbsp;&nbsp;&nbsp;联合开发
 				</div>

+ 1 - 0
src/js/api.js

@@ -7,6 +7,7 @@ const api = {
   entity_predict:'api/ltkg/nlp/getNlp',
   getMrInfo:'/api/ltkg/presetInfo/getMrInfo',
   getAnswer:'/api/ltkg/qa/charBot',
+  getTerm:'/api/ltkg/term/getTerm',
 };
 
 const getUrlArgObject = function(name) {//

+ 0 - 1
src/js/graphMap.js

@@ -281,7 +281,6 @@ function drawTree(data, showNodeName){
                         select_type_noSearch = select_type
                         setSelectName(select_type)
                     }
-                    console.log('aaaaaaaaaaaa', select_type)
                     getGraph(name,select_type)
                     const selectPId = $('.curSelectedNode').attr('id')
                     if(selectPId){

+ 274 - 1
src/js/medicalTermMap.js

@@ -1,4 +1,277 @@
 const $ = require("jquery");
 require("babel-polyfill");
 const echarts = require("echarts");
-require("./../css/medicalTermMap.less");
+require("./../css/medicalTermMap.less");
+require('./../resources/images/empty2.png');
+const { post, api } = require('./api.js');
+const { medicalTermDefaultMap } = require('./utils.js');
+
+window.select_type="disease";
+window.select_name="疾病";
+
+$("#infoTxt").bind("input propertychange",function(event){
+    const val = $("#infoTxt").val().trim();
+    if(!val){
+        $('#submit').addClass('disabled')
+    }else{
+        $('#submit').removeClass('disabled')
+    }
+});
+
+$(".submit").on("click",function(){
+    const val = $('#infoTxt').val().trim()
+    let param = {
+        word_type: select_type,
+        word: val,
+        number: 10
+    }
+    return post(api.getTerm,param).then(res =>{
+        if(res.data.code == 0){
+            const data = res.data.data 
+            let standardList = []
+            if(data){
+                dataObj = JSON.parse(data)
+                standardList = dataObj['standard_words'] || []
+                if(standardList.length > 0){
+                    getGraph(standardList[0].standard_word,select_name)
+                    renderStandrandWord(standardList)
+                }else{
+                    renderStandrandWord(standardList)
+                }
+                
+            }
+            
+        }else{
+            // getGraph(medicalTermDefaultMap[select_type],select_type)
+        }
+    })
+})
+
+//设置默认值
+setDefaultVal(medicalTermDefaultMap[select_type])
+$(".tabItem").click(function(){
+    const selectType = $(this).attr("data-type")
+    const selectName = $(this).attr("data-name")
+    select_type = selectType
+    select_name = selectName
+    $(this).addClass("activeTab").siblings().removeClass("activeTab")
+    setDefaultVal(medicalTermDefaultMap[select_type])
+
+})
+
+function setDefaultVal(val){
+    console.log('aaaaaaaaaa')
+    $("#infoTxt").val(val)
+    $(".submit").click()
+}
+
+
+function renderStandrandWord(list){
+    let str = ""
+    for(let i = 0; i < list.length; i++){
+        str += `<span class="resultItem ${i === 0 ? 'resultActive':''}" data-name="${list[i].standard_word}">${list[i].standard_word}</span>`
+    }
+    if(list.length === 0){
+        str="暂无结果~"
+        $(".emptyBox").css("display","block")
+    }
+    $(".mapResult").html(str)
+    bindResultItemClick()
+}
+function bindResultItemClick(){
+    $(".resultItem").off("click").on("click",function(){
+        $(this).addClass("resultActive").siblings().removeClass("resultActive")
+        const name = $(this).attr("data-name")
+        getGraph(name,select_name)
+    })
+}
+//关系图
+function getGraph(val, type){
+    return post(api.getGraph,{
+        "inputStr": val,
+        "labelName": type
+    }).then(res=>{
+        if(res.data.code == 0) {
+            // select_type = select_type_noSearch
+            drawGraph(res.data.data)
+            $(".emptyBox").css("display","none")
+        }else{
+           $(".emptyBox").css("display","block")
+        }
+    })
+}
+
+
+
+function drawGraph(data,resultShowId) {
+    // var colors = [
+    //     '#FB95AF','#788083','#B2CCCF','#68BDF6','#FFD86E','#6DCE9F','#9BB2F0','#DBB7AC'
+    // ]
+    var myChart = echarts.init(document.getElementById('main'));
+    var categories = data['categories'];
+    var legends = categories.slice(2, categories.length);
+    var option = {
+        // title: { 
+        //     text: '医学知识图谱',
+        //     top: '10',
+        //     left: '10'
+        // },
+        // color:colors,
+        tooltip: {
+            formatter: function (x) {
+                return x.data.label;
+            }
+        },
+        legend: [{
+            type: 'scroll',
+            bottom: 0,
+            icon: 'circle',
+            // cursor:'pointer',
+            data: legends.map(function (a) {
+                return a.name;
+            })
+        }],
+        series: [
+            {
+                type: 'graph',
+                layout: 'force',
+                cursor:'pointer',
+                categories: categories,
+                symbolSize: 80,
+                roam: 'move',
+                edgeSymbol: ['circle', 'arrow'],
+                edgeSymbolSize: [1, 5],
+                edgeLabel: {
+                    // cursor:'pointer',
+                    normal: {
+                        textStyle: {
+                            fontSize: 20
+                        }
+                    }
+                },
+                force: {
+                    repulsion: 500,
+                    gravity: 0.8,
+                    friction :0.2, //动画速度
+                    edgeLength: [4, 7],
+                    layoutAnimation : true
+                },
+                draggable: false,
+                animation: true,
+                hoverAnimation:false,
+                animationDuration:5000,
+                focusNodeAdjacency: true,
+                itemStyle: {
+                    normal: {
+                        width: 2,
+                        // color: 'target',
+                        // cursor:'pointer',
+                        curveness: 0,
+                        opacity: 1
+                    }
+                },
+                lineStyle: {
+                    normal: {
+                        width: 2,
+                        cursor:'default',
+                        color: 'target'
+                    }
+                },
+                edgeLabel: {
+                    normal: {
+                        show: true,
+                        formatter: function (x) {
+                            return x.data.value;  //横线关系
+                        }
+                    }
+                },
+                label: {
+                    normal: {
+                        show: true,
+                        textStyle: {
+                            cursor:'pointer',
+                        },
+                        color:'#1E1E1E', //label字体颜色
+                        formatter: function (x) {
+                             var tmp = x.data.label;
+                            if(tmp.length >= 12){
+                                tmp = tmp.substring(0,12);
+                                tmp = tmp + "...";
+                            }
+                            return tmp;
+                        }
+                    }
+                },
+                data: data.node,
+                links: data.links
+            }
+        ]
+    };
+    $(window).resize(function(){
+        myChart.resize(); 
+     })
+    // myChart.on('click',dataClick);
+    myChart.setOption(option);
+   
+}
+
+
+// function dataClick(param){
+//     var data = param.data;
+//     console.log('data',data)
+//     const clientHei = $(window).height()
+//     const contentHei = clientHei - 80
+//     // console.log('data', data,select_type)
+//     // var nodes = option.series[0].nodes;
+//     if(data.category == 0){
+//         return
+//     }else{
+//         if(data.symbol != "circle"){
+//             return
+//         }else{
+//             if(data.type == select_type){
+//                 $('#searchInp').val(data.label)
+//                 updateTree(data.label)
+//                 getGraph(data.label,select_type);
+              
+//             }else {
+//                 let renderTabInfo = getTab(data.type) 
+//                 renderTab(renderTabInfo) 
+               
+//                 if(data.type == "疾病"){
+//                     $(".radioList").show()
+//                     $('.iconRadio').attr('src','/images/radioUnSelect.png')
+//                     $('.ICD10 img').attr('src','/images/radioSelect.png')
+//                     setTabBottomHei(1)
+//                 }else{
+//                     $(".radioList").hide()
+//                     setTabBottomHei(2)
+//                 }
+//                 select_type_noSearch = data.type
+//                 select_type = data.type
+//                 setSelectName(select_type)
+//                 $('#searchInp').val(data.label)
+//                 if(data.type == "疾病"){
+//                     getTree(1,1,data.label);
+//                     getGraph(data.label,select_type);
+//                 }else if(data.type == "药品通用名"){
+//                     getTree(0,2,data.label);
+//                     getGraph(data.label,select_type);
+//                 }else if(data.type == "症状"){
+                  
+//                     getTree(0,3,data.label);
+//                     getGraph(data.label,select_type);
+//                 }else if(data.type == "手术和操作"){
+//                     getTree(0,4,data.label);
+//                     getGraph(data.label,select_type);
+//                 }else if(data.type == "实验室检查"){
+//                     getTree(0,5,data.label);
+//                     getGraph(data.label,select_type);
+//                 }else if(data.type == "辅助检查"){
+//                     getTree(0,6,data.label);
+//                     getGraph(data.label,select_type);
+//                 }
+//             }
+//         }
+//     }
+//  }

+ 12 - 0
src/js/utils.js

@@ -0,0 +1,12 @@
+const medicalTermDefaultMap={
+    "disease":"青光眼",
+    "symptom":"背痛",
+    "operation":"动脉缝合术",
+    "drug":"地辛高",
+    "lis":"白细胞计数",
+    "pacs":"肝彩超",
+}
+
+module.exports ={
+    medicalTermDefaultMap
+}

+ 1 - 1
webpack.config.js

@@ -6,7 +6,7 @@ const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
 const ExtractTextPlugin = require("extract-text-webpack-plugin");
 const webpack = require('webpack');
 const proxyHost = "http://192.168.2.236:5050";
-// const proxyHost = "http://192.168.3.119:5050";
+// const proxyHost = "http://192.168.3.113:5050";
 module.exports = {
   entry: {
     index: path.resolve(__dirname, 'src/js', 'index.js'),