糟糕!中二病要感染全人类了!

描述:当前是关于Echarts图表中的 示例。
 
            //关于这个图表我做的视频简介:https://www.bilibili.com/video/BV1pD4y127tW
//各位观众老爷们一键三连,下次一定!

//宅男数量
var nodesnum = 360
//中二病下毒机会
var xiadu = 1
//中二病的传染性,接触就传染的概率
var infectivity = 0.2
//治疗天数
var cureday = 4
//死亡率
var dierate = 0.2
//社区结构大小
var shequsize = 90
//社区内连接强度
var density = 0.35

$(`
    <div class="input-item chuan" @click="chuanbo">点击进行传播</div>
    <div class="text">传染性:0.2</div>
<input class="slider" type="range" min="0" max="0.5" value="0.2" step="0.01" style="">
<div class="textcure">潜伏期天数:4</div>
<input class="slidercure" type="range" min="2" max="30" value="4" step="1" style="">
<div class="textdie">致死率:0.2</div>
<input class="sliderdie" type="range" min="0" max="1" value="0.2" step="0.01" style="">
<div class="r0">估计R0:</div>
`).appendTo(
    $('#chart-panel')
);

$('.input-item').css({
    'position': 'absolute',
    'top': '180px',
    left: '10px',
    display: '-ms-flexbox',
    display: 'flex',
    '-ms-flex-wrap': 'wrap',
    'flex-wrap': 'wrap',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    width: '8rem',
    height: '2rem',
})

$('.chuan').css({
    display: '-webkit-box',
    display: '-ms-flexbox',
    display: 'flex',
    '-webkit-box-pack': 'center',
    '-ms-flex-pack': 'center',
    'justify-content': 'center',
    '-webkit-box-align': 'center',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    border: '1px solid #ced4da',
    'border-radius': '.25rem',
    'background-color': '#e9ecef',
    color: '#495057',
    'text-align': 'center',
    cursor: 'pointer'
})
$('.slider').css({
    'position': 'absolute',
    'top': '60px',
    left: '0.5rem',
    display: '-ms-flexbox',
    display: 'flex',
    '-ms-flex-wrap': 'wrap',
    'flex-wrap': 'wrap',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    width: '6rem',
    height: '2rem',
})
$('.text').css({
    'position': 'absolute',
    'top': '60px',
    left: '7rem',
    display: '-ms-flexbox',
    display: 'flex',
    '-ms-flex-wrap': 'wrap',
    'flex-wrap': 'wrap',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    width: '6rem',
    height: '2rem',
})
$('.slidercure').css({
    'position': 'absolute',
    'top': '100px',
    left: '0.5rem',
    display: '-ms-flexbox',
    display: 'flex',
    '-ms-flex-wrap': 'wrap',
    'flex-wrap': 'wrap',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    width: '6rem',
    height: '2rem',
})
$('.textcure').css({
    'position': 'absolute',
    'top': '100px',
    left: '7rem',
    display: '-ms-flexbox',
    display: 'flex',
    '-ms-flex-wrap': 'wrap',
    'flex-wrap': 'wrap',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    width: '10rem',
    height: '2rem',
})
$('.sliderdie').css({
    'position': 'absolute',
    'top': '140px',
    left: '0.5rem',
    display: '-ms-flexbox',
    display: 'flex',
    '-ms-flex-wrap': 'wrap',
    'flex-wrap': 'wrap',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    width: '6rem',
    height: '2rem',
})
$('.textdie').css({
    'position': 'absolute',
    'top': '140px',
    left: '7rem',
    display: '-ms-flexbox',
    display: 'flex',
    '-ms-flex-wrap': 'wrap',
    'flex-wrap': 'wrap',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    width: '10rem',
    height: '2rem',
})
$('.r0').css({
    'position': 'absolute',
    'top': '5px',
    left: '12rem',
    display: '-ms-flexbox',
    display: 'flex',
    '-ms-flex-wrap': 'wrap',
    'flex-wrap': 'wrap',
    '-ms-flex-align': 'center',
    'align-items': 'center',
    width: '10rem',
    height: '2rem',
})


var nodes = [{
    name: '0',
    category: 1
}]
var nodeindexes = []
//生成节点
for (var i = 1; i < nodesnum; i++) {
    nodes.push({
        name: i.toString(),
        category: 1
    })
    nodeindexes.push(i)

}



var links = []
//随机生成边
var items = []

function shequ(links, items, nodes, density) {
    var shequ1size = nodes.length
    for (var i = 0; i < shequ1size; i++) {
        for (var j = i; j < shequ1size; j++) {
            if (Math.random() < density*density * i / shequ1size * j / shequ1size && i != j) {
                links.push({
                    source: nodes[i].name,
                    target: nodes[j].name
                })
                items.push(nodes[i].name)
                items.push(nodes[j].name)
            }
        }
    }
    return links, items
}

for (var j = 0; j < nodesnum; j+=shequsize) {
    var start = Math.max(j-Math.floor(0.1*shequsize),0)
    var end = Math.min(j+shequsize+Math.floor(0.1*shequsize),nodesnum)
    var shequ1node = []
    for (var i = start; i < end; i++) {
        shequ1node.push(nodes[i])
    }
    links, items = shequ(links, items, shequ1node, density)
}

//补充边
for (var i = 0; i < nodesnum; i++) {
    if (items.indexOf(i.toString()) == -1) {
        nodeindexes.pop(i)
        links.push({
            source: i,
            target: nodeindexes[Math.floor(Math.random() * nodeindexes.length)]
        })
    }
}


//随机下毒一个人
nodes[Math.floor(Math.random()*nodesnum)].category = 0

//估计R0
var r0 = (2*cureday*infectivity*links.length/nodes.length).toFixed(2)

$('.r0').text('估计R0:' + r0)
$('.slider').change(function() {
    infectivity = this.value
    $('.text').text('传染性:' + infectivity)
    var r0 = (2*cureday*infectivity*links.length/nodes.length).toFixed(2)
    $('.r0').text('估计R0:' + r0)
})
$('.slidercure').change(function() {
    cureday = this.value
    $('.textcure').text('潜伏期天数:' + cureday)
    var r0 = (2*cureday*infectivity*links.length/nodes.length).toFixed(2)
     $('.r0').text('估计R0:' + r0)
})
$('.sliderdie').change(function() {
    dierate = this.value
    $('.textdie').text('致死率:' + dierate)
    var r0 = (2*cureday*infectivity*links.length/nodes.length).toFixed(2)
     $('.r0').text('估计R0:' + r0)
})


//去重函数
function unique(arr) {
    return Array.from(new Set(arr))
}

//病毒数
var viruscount = 1
var viruscounts = [[1, viruscount]]
var viruscounts_new = [[1, 0]]
var cures = [[1,0]]
var dies = [[1,0]]

//echarts的基础设置
option = {
    title: [{
        text: '中二病患者数:0',
        subtext: '你还有' + xiadu + '次下毒机会(点击目标下毒)'
    }, {
        text: '说明:\n2020年的某一天\n未知疾病突然出现\n迅速在宅男之间传播\n这一传说中的疾病被命名为:中二病\n每个点表示一个宅男\n点之间的连线代表宅男之间二次元的灵魂交流\n\n参数:\n传染性:每天交流传染中二病的概率\n潜伏期天数:潜伏期内会传染,潜伏期结束后\n隔离治疗,并判断治愈还是死亡\n\n怎么玩:\n你可以前期疯狂传染,后期调整参数防控\n如何控制传播?\n1.减少人与人的接触(图的边密度减少)\n2.戴口罩降低传染性(有交流就传染的概率降低)\n3.早发现早隔离避免潜伏期内传播(潜伏期天数减少)\n\n实现群体免疫:\n在传播到后期大部分人都治愈时(有抗体)再下毒\n虽然传染性强但也传播不开了',
                textStyle: {
            fontSize: 12
        },
        top: 'bottom',
        left: 'left'

    }
    ],
    grid: [{
        gridindex: 1,
        left: '35%',
        right: '3%',
        top: '5%',
        bottom: '75%',
        containLabel: true
    }],
    xAxis: [{
        name: '天',
        type: 'value',
        show: true,
        min: 0,
        max: 10,
        gridIndex: 0
    }],
    yAxis: [{
        name: '人数',
        type: 'value',
        show: true,

        gridIndex: 0
    }],
    tooltip: {},
    animationDurationUpdate: 1500,
    animationEasingUpdate: 'quinticInOut',
    legend:  [
              {data: ['感染者','未感染','治愈','死亡'],
              orient: 'vertical',
                        x: '0%',
                        y: '220px'},
              {data: ['中二病总患者数', '中二病新增患者数','中二病治愈数','中二病死亡数'],
   
                        x: '70%',
                        y: '0%'}
            ],
    
    
    series: [{
            type: 'graph',
            name: '宅男',
            layout: 'force',
            symbolSize: 12,
            roam: true,
            top: '24%',
            label: {
                fontSize: 12,
                show: false
            },
            edgeSymbol: ['circle', 'circle'],
            edgeSymbolSize: [4, 4],
            edgeLabel: {
                fontSize: 10
            },
            categories: [{
                name: '感染者'
            }, {
                name: '未感染'
            }, {
                name: '治愈'
            }, {
                name: '死亡'
            }],
            data: nodes,
            // links: [],
            links: links,
            lineStyle: {
                opacity: 0.9,
                width: 1.5,
                curveness: 0
            },
            draggable: true,
            force: {
                repulsion: 20,
                gravity: 0.12,
                edgeLength: 1
            }
        },
        {
            xAxisIndex: 0,
            yAxisIndex: 0,
            name: '中二病总患者数',
            type: 'line',
            showSymbol: false,
            data: viruscounts,
            itemStyle: {normal: {color: '#C23531'}}
        },
        {
            xAxisIndex: 0,
            yAxisIndex: 0,
            name: '中二病新增患者数',
            type: 'line',
            showSymbol: false,
            data: viruscounts,
            itemStyle: {normal: {color: '#2f4554'}}
        },
        {
            xAxisIndex: 0,
            yAxisIndex: 0,
            name: '中二病治愈数',
            type: 'line',
            showSymbol: false,
            data: viruscounts,
            itemStyle: {normal: {color: '#61A0A8'}}
        },
        {
            xAxisIndex: 0,
            yAxisIndex: 0,
            name: '中二病死亡数',
            type: 'line',
            showSymbol: false,
            data: viruscounts,
            itemStyle: {normal: {color: '#D48265'}}
        }
    ]
};

myChart.setOption(option);




var t = 1
var score = 0
var gameend = 0
$(".chuan").click(function() {
    
    
    //计算分数
    score += parseInt(infectivity*100)
    //找到红的点
    var virusitem = []
    for (eachnodeinfo in nodes) {
        if (nodes[eachnodeinfo].category == 0) {

            virusitem.push(nodes[eachnodeinfo].name)
        }
    }
    //找到红的点连接的点,新的感染者
    var virusitem_new = []
    for (linkinfo in links) {
        //console.log(links[linkinfo].source.toString())
        if (virusitem.indexOf(links[linkinfo].source.toString()) != -1) {
            if (Math.random() < infectivity) {
                if (nodes[links[linkinfo].target].category==1){
                virusitem_new.push(links[linkinfo].target)}
            }
        }
        if (virusitem.indexOf(links[linkinfo].target.toString()) != -1) {
            if (Math.random() < infectivity) {
                if (nodes[links[linkinfo].source].category==1){
           
                virusitem_new.push(links[linkinfo].source)}
            }
        }
    }
    //感染者加入
    for (virusitem_new_id in virusitem_new) {
        virusitem_new_id = virusitem_new[virusitem_new_id]
        virusitem.push(virusitem_new_id.toString())
    }

    virusitem = unique(virusitem)

    //更新患者信息
    for (nodes_id in nodes) {
        if (virusitem.indexOf(nodes[nodes_id].name.toString()) != -1) {
            nodes[nodes_id].category = 0
            if (nodes[nodes_id].infecttime){}else{
            nodes[nodes_id].infecttime = t}
        }
    }
    
    //判断治愈情况
    for (nodes_id in nodes) {
        if (t-nodes[nodes_id].infecttime>cureday & nodes[nodes_id].category==0){
            if (Math.random()<dierate){
        nodes[nodes_id].category=3}else{nodes[nodes_id].category=2}
        }
    }

    //计数
    cure = 0
    die = 0
    for (nodes_id in nodes) {
    if (nodes[nodes_id].category==2){cure+=1}
    if (nodes[nodes_id].category==3){die+=1} 
    }
    t += 1
    viruscounts.push([t, virusitem.length])
    viruscounts_new.push([t, virusitem.length - viruscount])
    cures.push([t,cure])
    dies.push([t,die])
    
    optionchange = {
        title: [{
            text: '中二病患者数:' + virusitem.length,
            subtext: '你还有' + xiadu + '次下毒机会(点击目标下毒)'
        }],
        xAxis: [{
            max: 2 + t
        }],
        series: [{
            data: nodes
        }, {
            data: viruscounts
        }, {
            data: viruscounts_new
        }, {
            data: cures
        }, {
            data: dies
        }]
    }
    myChart.setOption(optionchange);

    //病毒数
    //判断游戏结束
    //计算分数
    
    if (viruscount == 0 & xiadu == 0 &gameend == 0) {
        alert('游戏结束,你的得分是:'+((score*density*1000/t)/(cure+die)).toFixed(2)+'分')
        gameend = 1
    }
    viruscount = virusitem.length

})



myChart.on('click', function(p) {
    if(p.dataType=='node'){
    if (xiadu > 0) {
        xiadu -= 1

        //找到红的点
        var virusitem = []
        for (eachnodeinfo in nodes) {
            if (nodes[eachnodeinfo].category == 0) {

                virusitem.push(nodes[eachnodeinfo].name)
            }
        }


        //更新点击的点
        nodes[p.name].category = 0

        //重新计算感染者数量
        for (eachnodeinfo in nodes) {
            if (nodes[eachnodeinfo].category == 0) {
                virusitem.push(nodes[eachnodeinfo].name)
            }
        }

        //去重
        virusitem = unique(virusitem)

        //更新点
        for (nodes_id in nodes) {
            if (virusitem.indexOf(nodes[nodes_id].name.toString()) != -1) {
                nodes[nodes_id].category = 0
                nodes[nodes_id].infecttime = t
            }
        }
        optionchange = {
            title: [{
                text: '中二病患者数:' + virusitem.length,
                subtext: '你还有' + xiadu + '次下毒机会(点击目标下毒)'
            }],
            xAxis: [{
                max: 2 + t
            }],
            series: [{
                data: nodes
                
            }]
        }
        myChart.setOption(optionchange);

        //病毒数
        viruscount = virusitem.length
    }
}})