当前位置: 首页 > 知识库问答 >
问题:

javascript - 请教大佬们,使用echart绘制心电图?

闾丘永春
2023-05-22

如下图想通过echart绘制下面的心电图
1.心电电压在-400~400之间 放大了100倍
2.心电的采样率是250hz,采样时间为30秒,所有会有7500个数据,一次性渲染
3.图表横坐标以每一秒为一大格,每一大格中有5个中格,每一个中格有5个小格,纵坐标区间为-2.5mv~1.5mv
4.心电图可以往右滑动
有会的大佬,可以有偿,谢谢

共有3个答案

高展
2023-05-22

打开看一下,我这也是动态的。
https://www.chunshu.net/pic/2/#/Three?val=1&name=%E8%83%83%E7...

image.png

<template>
    <div class="home">
        <div class="home_top">
            <Videox :src="require('../assets/media/head.mp4')"></Videox>
            <div class="topCss">
                <div class="topCssL">
                    <span  @click="goHome"> 首页>></span>{{name}}
                </div>
                <div class="timeCss timeStyle">
                    <span>{{nowTime1}}</span>
                    <span>{{nowTime2}}</span>
                </div>
            </div>
        </div>
        <el-row class="homeAll" :gutter="20">
            <el-col :span="6">
                <div class="twoTitle leftAnimation1">
                    <div>典型患者病例档案</div>
                    <span style="cursor: pointer">{{name}}</span>
                </div>
                <div class="threeTen leftAnimation1">
                    <div class="ten">
                        <countTo  class="fontCss1" :decimals=1 separator="" :startVal=0 :endVal=80 :duration="3000"></countTo>
                        <p>体温</p>
                    </div>
                    <div class="ten">
                        <countTo  class="fontCss1" :decimals=0  separator="" :startVal=0 :endVal=80 :duration="3000"></countTo>
                        <span>次/分</span>
                        <p>脉博</p>
                    </div>
                    <div class="ten">
                        <countTo  class="fontCss1" :decimals=0  separator="" :startVal=0 :endVal=120 :duration="3000"></countTo>
                        <span>次/分</span>
                        <p>呼吸</p>
                    </div>
                    <div class="ten">
                        <span class="fontCss1">112/75mmHg</span>
                        <p>血压</p>
                    </div>
                </div><br/><br/>
                <div class="homeTitle leftAnimation1">历史诊断记录</div><br/>
                <div class="threeLTwo leftAnimation1" style="height: 300px">
                    <div class="linexTop"><span></span><span></span></div>
                    <div class="haoba">
                        <div class="threeLTwoOne">
                            就诊医生:寅春树<br/>
                            就诊医生:杭州第三人民医院(北院区)<br/>
                            就诊科室:消化内科<br/>
                        </div>
                        <div class="threeLTwoTwo biling haoba1">
                            主诉:患者3月余前无明显诱因下出现呕血,呈鲜红色,量约1-2L,伴胃内容物,伴头晕黑朦,伴大汗淋漓,伴黑便,遂至地方人民医院就诊,争诊予止血补液等对症支持治疗(具体药物不详)后症状好转,后未再呕血,后患者至当地医院复查胃镜。
                            <div style="margin-top: 10px">即往史:患者发现粮尿病10余年,平时服用“格列美脲2mg qd控制,自述血糖控制可。</div>
                        </div>

                    </div>
                    <div class="linexBottom"><span></span><span></span></div>
                </div><br/>
                <div class="homeTitle leftAnimation2">手术记录</div><br/>
                <div class="threeLTwo leftAnimation2">
                    <div class="linexTop"><span></span><span></span></div>
                    <div class="threeLTwoTwo biling haoba2">
                        腹腔锐下贲门癌根治(全胃切除+D2淋巴结清扫+食道空肠R-Y吻合)+肠粘连松解+筋膜组织瓣成形+腹壁整形术。
                    </div>
                    <div class="linexBottom"><span></span><span></span></div>
                </div><br/>
                <div class="homeTitle leftAnimation3">术后并发症及风险管理</div><br/>
                <div class="threeLthree leftAnimation3">
                    <div class="linexTop"><span></span><span></span></div>
                    <div class="gundong" ref="gundong">
                        <div class="threeLthree1">术后十二根肠残端漏,胆漏,吻合口瘘,吻合口出血,狭窄、梗阻、腹盆腔出血,大出血保守治疗无效,需再次手术止血可能;</div>
                        <div class="threeLthree1">术后肠粘连、肠梗阻,再次手术可能;</div>
                        <div class="threeLthree1">术后十二根肠残端漏,胆漏,吻合口瘘,吻合口出血,狭窄、梗阻、腹盆腔出血,大出血保守治疗无效,需再次手术止血可能;</div>
                        <div class="threeLthree1">术后十二根肠残端漏,胆漏,吻合口瘘,吻合口出血,狭窄、梗阻、腹盆腔出血,大出血保守治疗无效,需再次手术止血可能;</div>
                        <div class="threeLthree1">术后十二根肠残端漏,胆漏,吻合口瘘,吻合口出血,狭窄、梗阻、腹盆腔出血,大出血保守治疗无效,需再次手术止血可能;</div>
                        <div class="threeLthree1">术后肠粘连、肠梗阻,再次手术可能;</div>
                    </div>
                    <div class="linexBottom"><span></span><span></span></div>
                </div>
            </el-col>
            <el-col :span="12">
                <div class="twoCenter">
                    <div class="threeTwo">
                            <div class="ok"><span></span><span @click="refresh">2022-07-01</span></div>
                            <div><span></span><span @click="refresh">2022-06-20</span></div>
                            <div><span></span><span @click="refresh">2022-05-20</span></div>
                            <div><span></span><span @click="refresh">2022-05-19</span></div>
                            <div><span></span><span @click="refresh">2022-05-16</span></div>
                            <div><span></span><span @click="refresh">2022-05-14</span></div>
                    </div>
                    <div class="threeOne">
                        <img class="threeCirle" src="../assets/img/three5.png"/>
                        <img class="threeMove" src="../assets/img/two6.png"/>
                    </div>
                    <img class="leftTop" src="../assets/img/two3.png"/>
                    <img class="leftRight" src="../assets/img/two3.png"/>
                    <img class="leftBottom" src="../assets/img/two3.png"/>
                    <img class="rightBottom" src="../assets/img/two3.png"/>
                </div>
            </el-col>
            <el-col :span="6">
                <div class="homeTitle rightAnimation1">CT/增强CT/胃镜</div><br/>
                <div class="threeRone rightAnimation1">
                    <img src="../assets/img/three3.png"/>
                </div><br/>
                <div class="homeTitle rightAnimation2">常规心电图</div><br/>
                <div id="totalFlowRate"  class="threeRtwo rightAnimation2"></div><br/>
                <div class="homeTitle rightAnimation3">实验室检验</div>
                <div class="twoRfour rightAnimation3">
                    <div class="linexTop"><span></span><span></span></div>
                    <div class="twoRfourOne threeCssX">
                        <span>检验指标</span>
                        <span>值</span>
                        <span>提示</span>
                        <span>单位</span>
                        <span>参考区间</span>
                    </div>
                    <div ref="twoRfourTwo" class="twoRfourTwo threeCssX">
                        <li>
                            <span>腺苷酸脱氨酶/血液</span>
                            <span>18.9</span>
                            <span></span>
                            <span>U/L</span>
                            <span>8~24</span>
                        </li>
                        <li>
                            <span>总胆红素/血液</span>
                            <span>8.9</span>
                            <span></span>
                            <span>μmol/L</span>
                            <span>1.7~17.1</span>
                        </li>
                        <li>
                            <span>白细胞计数/血液</span>
                            <span>6.2</span>
                            <span></span>
                            <span>10E9/L</span>
                            <span>10E9/L    4.0~10.0</span>
                        </li>
                        <li>
                            <span>肾小球滤过率(EPI-cr)/血清</span>
                            <span>104.67</span>
                            <span>↓</span>
                            <span>ml/min</span>
                            <span>ml/min    125土15</span>
                        </li>
                        <li>
                            <span>淋巴细胞(%)/血液</span>
                            <span>15.3</span>
                            <span>↓</span>
                            <span>%</span>
                            <span>%    17-50</span>
                        </li>
                        <li>
                            <span>谷丙转氨酶/血液</span>
                            <span>17</span>
                            <span></span>
                            <span>U/L</span>
                            <span>0-40</span>
                        </li>
                        <li>
                            <span>肾小球滤过率(EPI-cr)/血清</span>
                            <span>104.67</span>
                            <span>↓</span>
                            <span>ml/min</span>
                            <span>ml/min    125土15</span>
                        </li>
                        <li>
                            <span>淋巴细胞(%)/血液</span>
                            <span>15.3</span>
                            <span>↓</span>
                            <span>%</span>
                            <span>%    17-50</span>
                        </li>
                        <li>
                            <span>谷丙转氨酶/血液</span>
                            <span>17</span>
                            <span></span>
                            <span>U/L</span>
                            <span>0-40</span>
                        </li>

                    </div>

                    <div class="linexBottom"><span></span><span></span></div>
                </div>
            </el-col>
        </el-row>
        <div class="home_bj">
            <img src="../assets/img/home_bj.png">
        </div>
    </div>
</template>

<script>
    import Videox from '@/components/Video'
    import countTo from 'vue-count-to'
    export default {
        name: "Three",
        components: {
            countTo,Videox
        },
        data(){
            return{
                nowTime1:null,
                nowTime2:null,
                val:null,
                name:''
            }
        },
        mounted() {
            this.getData()
            this.nowTimes()
            this.flowRate()

            let heigh=this.$refs.gundong.scrollTop
            this.gun=setInterval(()=>{
                if(heigh<250){
                    heigh=heigh+1
                    this.$refs.gundong.scrollTop=heigh
                }else{
                    clearInterval(this.gun)
                }
            },100)

            let heigh1=this.$refs.twoRfourTwo.scrollTop
            this.gun2=setInterval(()=>{
                if(heigh1<300){
                    heigh1=heigh1+1
                    this.$refs.twoRfourTwo.scrollTop=heigh1
                }else{
                    clearInterval(this.gun2)
                }
            },100)

        },
        methods:{
            getData(){
                this.name=this.$route.query.name
                this.val=this.$route.query.val
            },
            refresh(){
                location.reload()
            },
            flowRate(){
                var xAxisData = [];
                var yAxisData = [];
                for (var i = 50; i > 0; i--) {
                    xAxisData.push(i + "秒前");
                }
                for (i = 1; i < 51; i++) {
                    yAxisData.push(null);
                }
                var myChart = this.$echarts.init(document.getElementById("totalFlowRate"));
               let option={
                   animation: false,
                   color:"#00E4E0",

                   tooltip: {
                       trigger: 'axis',
                       axisPointer: { type: 'cross' }
                   },
                   grid: {
                       left: 50/*"50px"*/,
                       bottom:20,
                       right: 15/*"15px"*/
                   },
                   legend: {
                       data: ['当前流量'],
                       orient: "horizontal",
                       top: '5%',
                       right:'20px',
                       textStyle:{
                           color:"#B8C4D2",
                           fontSize:"15px",
                       }
                   },
                   xAxis: {
                       boundaryGap: false,
                       data: xAxisData,
                   },
                   yAxis: {
                       boundaryGap: false,
                       splitLine:{
                           show:false,
                       },
                   },
                   series: {
                       symbol: "none",/*去掉小圆点*/
                       name: '当前流量',
                       type: 'line',
                       data: yAxisData,
                       /*smooth:true*/
                   }}
                myChart.setOption(option);
                setInterval(function () {
                    yAxisData.push(Math.round(Math.random() * 1000));
                    if(yAxisData.length>50) {
                        yAxisData.shift();
                    }
                    myChart.setOption(option);
                }, 100);
            },
            goHome(){
                this.$router.push({
                    path:'./'
                })
            },
            timeFormate(timeStamp) {
                let year = new Date(timeStamp).getFullYear();
                let month =new Date(timeStamp).getMonth() + 1 < 10? "0" + (new Date(timeStamp).getMonth() + 1): new Date(timeStamp).getMonth() + 1;
                let date =new Date(timeStamp).getDate() < 10? "0" + new Date(timeStamp).getDate(): new Date(timeStamp).getDate();
                let hh =new Date(timeStamp).getHours() < 10? "0" + new Date(timeStamp).getHours(): new Date(timeStamp).getHours();
                let mm =new Date(timeStamp).getMinutes() < 10? "0" + new Date(timeStamp).getMinutes(): new Date(timeStamp).getMinutes();
                let ss =new Date(timeStamp).getSeconds() < 10? "0" + new Date(timeStamp).getSeconds(): new Date(timeStamp).getSeconds();
                this.nowTime1 = year + "年" + month + "月" + date +"日";
                this.nowTime2 = hh+":"+mm+':'+ss ;
            },
            nowTimes(){
                this.timeFormate(new Date());
                setInterval(this.nowTimes,1000);
                this.clear()
            },
            clear(){
                clearInterval(this.nowTimes)
                this.nowTimes = null;
            },
        }
    }
</script>

<style lang="less" scoped>
    .threeTwo div,.threeTwo span{transition: all 0.5s;-moz-transition: all 0.5s;-webkit-transition: all 0.5s;-o-transition: all 0.5s}
    .twoTitle{color: #66E1DF;font-size: 30px;text-align: left;font-family: siyuan !important;height: 35px;line-height: 35px;display: flex}
    .twoTitle div{font-family: siyuanBold!important;}
    .twoTitle span{background: #009DFF;font-size: 20px;font-family: siyuanLight!important;color: #fff;padding:0px 5px;margin-left: 10px;border-radius: 3px;display: block;}

    .threeLone{color: #6C8097;font-family: roboto!important;display: flex;justify-content: space-between;margin-top: 30px;align-items: flex-start;text-align: left;width: 445px;
        div{span:nth-child(2){display: inline-block;font-family: siyuanBold!important;font-size: 14px;color: #00E8E2}}
    }

    .fontCss1{font-family: roboto !important;color: #00E8E2;font-weight: bold;font-size:20px;height:30px;display: inline-block}
    .threeLTwo{background:rgba(52,52,52,.19);padding:10px 20px;position: relative;text-align: left;color: #F4F4F4;width: 445px;}
    .threeLTwoOne{line-height: 25px;font-size: 15px;color: #BBCEE5}
    .threeLTwoTwo{padding-top: 10px;font-size: 14px;line-height: 30px;color: #BBCEE5;overflow-y: auto;}
    .threeLthree{position: relative;background: rgba(52,52,52,.19);padding:10px 20px;text-align: left;color: #BBCEE5;font-size: 14px;line-height: 30px;width: 445px;}
    .threeLthree1{margin: 5px auto;background: rgba(52,52,52,.19);padding-left: 20px;}

    .threeRone{border: 1px solid #406277;padding:10px;background:rgba(52,52,52,.19);width: 445px;}
    .threeRone img{max-width: 100%;}
    .twoRfour{background: rgba(52,52,52,.19);height: auto;overflow: hidden;padding:15px;position: relative;margin-top: 10px;width: 445px;}

    .twoRfourOne{display: flex;justify-content: space-around;color:#64DDDB;height: 45px;line-height: 45px;}
    .twoRfourTwo{height: 300px;overflow-y:auto;}
    .twoRfourTwo li{list-style: none;display: flex;justify-content: space-around;color: #C6D3E1;font-family: siyuanLight!important;font-size:14px;height: 40px;line-height: 40px;}
    .twoRfourTwo li:nth-child(odd){background: #1F262B}
    .threeRtwo{padding:10px;border: 1px solid #406277;background: url("../assets/img/three2.png");width: 445px;height: 270px;}

    .twoCenter{position: relative;padding:10px;text-align: left;height: auto;overflow: hidden}
    .leftTop{position: absolute;left:0;top:0}
    .leftRight{position: absolute;right:0;top:0;transform:rotate(90deg);-ms-transform:rotate(90deg);-moz-transform:rotate(90deg);-webkit-transform:rotate(90deg);-o-transform:rotate(90deg); }
    .leftBottom{position: absolute;left:0;bottom:0;transform:rotate(-90deg);-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-o-transform:rotate(-90deg); }
    .rightBottom{position: absolute;right:0;bottom:0;transform:rotate(-180deg);-ms-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-webkit-transform:rotate(-180deg);-o-transform:rotate(-180deg); }

    .threeOne{width: 619px;height:725px;background: url("../assets/img/two5.png") no-repeat center center;margin: 10% auto 0px auto;position: relative;}
    .threeOne img{position: absolute;left: -15%;top:0px;}
    .threeMove{animation: 2s threeMove linear infinite;}

    .threeTwo{width: 90%;height: auto;overflow: hidden;display: flex;justify-content: flex-start;flex-wrap:wrap;margin-left: 90px}

    .threeTwo div{width: 120px;height: 36px;line-height: 36px;color: #AAB5C3;text-align: center;cursor: pointer;font-family: robotoLight!important;font-size: 14px;position: relative}
    .threeTwo div span:nth-child(1){width: 6px;height: 6px;display: inline-block;background: #6C8097;border-radius: 50%;margin-right: 10px;position: absolute;top:14px;left:16px;}
    .threeTwo .ok{border:1px solid #92D6FF;background: #1077C4;position: relative}
    .threeTwo .ok span:nth-child(1){background: #fff;position: absolute;top:14px;left:16px;}
    .threeTwo div:hover{background: #1077C4;color: #fff;border:1px solid #92D6FF;}
    .threeTwo div:hover .threeTwo .ok span:nth-child(1){color: #fff;}

    .threeCirle{position: absolute;left:44%!important;top:37%!important;animation: 1s biling linear infinite}

    .haoba2::-webkit-scrollbar,.haoba1::-webkit-scrollbar,.threeLTwo::-webkit-scrollbar,.gundong::-webkit-scrollbar{
        width: 10px;
        height: 1px;
    }
    .haoba2::-webkit-scrollbar-thumb,.haoba1::-webkit-scrollbar-thumb,.threeLTwo::-webkit-scrollbar-thumb,.gundong::-webkit-scrollbar-thumb{
        border-radius: 10px;
        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
        background: #66e1df;
    }
    .haoba2::-webkit-scrollbar-track,.haoba1::-webkit-scrollbar-track,.threeLTwo::-webkit-scrollbar-track,.gundong::-webkit-scrollbar-track{
        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
        border-radius: 10px;
        background: #0A1013;
    }
    /*.threeLTwo::-webkit-scrollbar-track-piece,.threeLthree::-webkit-scrollbar-track-piece{
        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
        border-radius: 10px;
        background: #EDEDED;
    }*/
    .threeCssX{text-align: left;}
    .threeCssX span,.threeCssX li span{display: inline-block;width: 20%;}
    .threeCssX span:nth-child(1){overflow: hidden;
        text-overflow:ellipsis;
        white-space: nowrap;}
    .threeCssX li{padding:0px 10px;}
    .gundong{height: 250px;overflow-y: auto;}
    .threeTen{
        height: auto;overflow: hidden;margin-top: 30px;
        .ten{float: left;width: 22%;text-align: left;
            span{display: inline-block};
            span:nth-child(2){color: #00E6E0;font-family: siyuanBold!important;}
            p{color: #6C8097;}
        }
    }
    .haoba1{height: 225px;overflow-y: auto}
    .haoba2{height: 70px;overflow: hidden;overflow-y: auto;}
</style>
孔权
2023-05-22

之前有做过类似的,仅供参考哈

// 心电数据
const data = [];
const voltageMultiplier = 100;
const sampleRate = 250;
const samplingTime = 30;
const totalDataPoints = sampleRate * samplingTime;

for (let i = 0; i < totalDataPoints; i++) {
  const time = i / sampleRate;
  const voltage = Math.random() * 800 - 400; // 生成-400到400之间的随机电压
  data.push([time, voltage]);
}

// 初始化图表
const chart = echarts.init(document.getElementById('chart'));

const option = {
  tooltip: {
    trigger: 'axis',
    formatter: '时间:{b}s<br/>电压:{c}mv'
  },
  xAxis: {
    type: 'value',
    name: '时间(s)',
    splitLine: {
      show: false
    }
  },
  yAxis: {
    type: 'value',
    name: '电压(mv)',
    min: -250,
    max: 150,
    splitLine: {
      show: true
    }
  },
  series: [
    {
      type: 'line',
      data: data,
      symbol: 'none',
      lineStyle: {
        color: 'blue',
        width: 1
      },
      areaStyle: {
        color: 'rgba(30,144,255,0.3)'
      }
    }
  ]
};

// 渲染图表
chart.setOption(option);

// 添加滚动功能
chart.getZr().on('mousewheel', function (params) {
  const scrollDelta = params.wheelDelta; // 滚动的增量,正负表示滚动方向
  const zoomDelta = scrollDelta > 0 ? -0.1 : 0.1; // 缩放增量
  chart.setOption({
    dataZoom: [
      {
        start: chart.getOption().dataZoom[0].start + zoomDelta,
        end: chart.getOption().dataZoom[0].end + zoomDelta
      },
      {
        start: chart.getOption().dataZoom[1].start + zoomDelta,
        end: chart.getOption().dataZoom[1].end + zoomDelta
      }
    ]
  });
});

首先,生成了7500个模拟的心电数据点,并根据给定的放大倍数进行了放大处理。然后,创建了一个基于时间和电压的折线图,并将数据点传入图表进行绘制。纵坐标设置了合适的范围,横坐标以每秒为一大格,每大格有5个中格,每个中格有5个小格。最后,通过监听鼠标滚轮事件,实现了图表的水平滚动功能。

强硕
2023-05-22

查下文档,找到对应配置项修改下不就行了?参考这个示例:https://echarts.apache.org/examples/zh/editor.html?c=line-fun...
然后修改配置已符合你的样式需求,比如修改xAxis.splitNumber设置网格数目,修改grid.width为固定数值,取消自适应则溢出可滚动,数据这方面就不用多说了

 类似资料:
  • 流程: 问题: 求教各位朋友,这个情况如何解决? 代码: 结果 数组置空, setSessionList([]) 这一步没有什么作用 补充 需求就是点击左边不同的用户,右边显示与当前用户的会话数据列表 现在的问题是,我点击多个用户后,显示的是这多个用户所有的会话数据列表,而我只需要显示当前被点击的这个用户的会话数据列表 比如: 与A用户的会话数据是 [{id:1}, {id:2}] 当我依次点击A

  • 本人想入坑golang来做web开发,向大佬们请教些问题(感谢指教),如下: 1.请推荐一下golang web框架(原因) 2.请推荐一些golang web框架写的应用的开源的代码,例如写的论坛呀,即时通信呀,流量统计呀等等(学习参考) 3.golang做web的优势说明 求指教!!!!!非常感谢!!!!!

  • 请问下面的 model 参数的类型该如何定义呢? 我试了半天,好像没有办法

  • 本文向大家介绍JavaScript实现使用Canvas绘制图形的基本教程,包括了JavaScript实现使用Canvas绘制图形的基本教程的使用技巧和注意事项,需要的朋友参考一下 由于这两年HTML5火的正热,所以研究了一下,最近有个想法也是要用到HTML的相关功能,所以也要好好学习一把。 好好看了一下Canvas的功能,感觉HTML5在客户端交互的功能性越来越强了,今天看了一下Canvas绘图,

  • 有没有大佬提供下这种echart 图表的示例参考一下