Built with blockbuilder.org
Created
June 20, 2020 11:35
-
-
Save ninjakx/8d879d031312c80320eae76160b630da to your computer and use it in GitHub Desktop.
tip display
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
.parent { | |
display: flex; | |
flex-wrap: wrap; | |
margin-left: 10vw; | |
margin-right: 10vw; | |
margin-top: 1%; | |
} | |
.child { | |
flex: 1 10 20%; /* explanation below */ | |
margin-left: 1%; | |
margin-right: 1%; | |
height: 12.5vw; | |
background-color: blue; | |
} | |
#kpi { | |
padding: 10px 0; | |
/*display: flex;*/ | |
flex-wrap: wrap; | |
} | |
#kpi-confirmed { | |
color: #f44334; | |
} | |
#kpi #kpi-active { | |
color: #1876d3; | |
} | |
#kpi #kpi-recovered { | |
color: #389e05; | |
} | |
#kpi #kpi-death { | |
color: #36484f; | |
} | |
/*#kpi .kpi-box { | |
}*/ | |
#kpi .kpi-box { | |
padding: 0.8rem; | |
/*width: 210px;*/ | |
line-height: 1.3rem; | |
/*height: 11rem;*/ | |
display: block | |
} | |
#kpi .kpi-box { | |
background: #fff; | |
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2); | |
border-radius: 10px; | |
margin: 5px 5px; | |
} | |
#kpi .kpi-box .diff { | |
font-size: 1rem; | |
line-height: 1em; | |
font-weight: 700; | |
display: inline; | |
word-wrap: none; | |
} | |
#kpi .kpi-box .value { | |
font-size: 1.4rem; | |
font-weight: 800; | |
display: inline; | |
} | |
#kpi .kpi-box .label { | |
color: #000a12; | |
font-size: 0.9rem; | |
font-weight: 800; | |
margin-bottom: 0.5rem; | |
} | |
* { | |
box-sizing: border-box; | |
} | |
/* Create three equal columns that floats next to each other */ | |
.column { | |
float: left; | |
width: 33.3%; | |
padding: 10px; | |
height: 25vw; /* Should be removed. Only for demonstration */ | |
} | |
/* Clear floats after the columns */ | |
.row:after { | |
content: ""; | |
display: table; | |
clear: both; | |
} | |
/*#ui { | |
width:50% !important; | |
} | |
*/ | |
.irs--round .irs-grid-text { | |
color: #002bff !important; | |
} | |
.irs--round .irs-grid-pol { | |
background-color: #6644df !important; | |
} | |
.irs--round.irs-with-grid { | |
/*height: 65px;*/ | |
width: 93% !important; | |
left: 3% !important; | |
margin-bottom: 1%; | |
} | |
#interval { | |
width:100px; | |
} | |
</style> | |
<head> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.9/dc.min.css"> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.7/crossfilter.js"></script> | |
<!-- <script src="d3.slider.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.1/d3.js"></script> --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.2.1/dc.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/reductio/1.0.0/reductio.js"></script> | |
</head> | |
<!--Plugin CSS file with desired skin--> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/css/ion.rangeSlider.min.css"/> | |
<!--jQuery--> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> | |
<!--Plugin JavaScript file--> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.1/js/ion.rangeSlider.min.js"></script> | |
<!-- | |
<div class="range-slider"> | |
<input type="text" class="js-range-slider" value="" /> | |
</div> | |
<div class="extra-controls"> | |
<input type="text" class="js-input" value="0" /> | |
</div> --> | |
<!-- <div id="ui"></div> --> | |
<div class="parent" id="kpi"> | |
<div class="child kpi-box" id="kpi-confirmed" value="confirmed" checked="true"> | |
<div class="label" data-i18n="kpi-confirmed">Confirmed</div> | |
<div class="value"></div> | |
<div class="diff"></div> | |
<div class="description"></div> | |
<div id="daily_conf"></div> | |
<div class="chart-caption" data-i18n="confirmed-chart-caption">Daily new cases</div> | |
</div> | |
<div class="child kpi-box" id="kpi-active" value="active"> | |
<div class="label" >Active</div> | |
<div class="value"></div> | |
<div class="diff"></div> | |
<div class="description"></div> | |
<div id="daily_actv"></div> | |
<div class="chart-caption" data-i18n="active-chart-caption">Daily new cases</div> | |
</div> | |
<div class="child kpi-box" id="kpi-recovered" value="recovered"> | |
<div class="label">Recovered</div> | |
<div class="value"></div> | |
<div class="diff"></div> | |
<div class="description"></div> | |
<div id="daily_recov"></div> | |
<div class="chart-caption" data-i18n="recovered-chart-caption">Daily new cases</div> | |
</div> | |
<div class="child kpi-box" id="kpi-death" value="deaths"> | |
<div class="label">Death</div> | |
<div class="value"></div> | |
<div class="diff"></div> | |
<div class="description"></div> | |
<div id="daily_dcsd"></div> | |
<div class="chart-caption" data-i18n="death-chart-caption">Daily new cases</div> | |
</div> | |
</div> | |
<div id="ui"></div> | |
<div class="row"> | |
<div class="column" style="background-color:#aaa;"> | |
<!-- <h2>Column 1</h2> --> | |
<div id="total_cases" class="svg-container"> | |
<div class="chart-title"> | |
<span style="font-size: 1.1em"> | |
<strong>Total Cases</strong> | |
<br> | |
</span> | |
</div> | |
</div> | |
</div> | |
<div class="column" style="background-color:#bbb;"> | |
<div id="line-chart" class="svg-container"> | |
<div class="chart-title"> | |
<span> | |
<strong>Total Cases Statewise</strong> <select id="interval"></select> | |
<br> | |
</span> | |
</div> | |
</div> | |
</div> | |
<div class="column" style="background-color:#ccc;"> | |
<div id="line-chart2" class="svg-container"> | |
<div class="chart-title"> | |
<span> | |
<strong>Daily Cases</strong> | |
<br> | |
</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
map_state = {"Andaman and Nicobar Islands": "AN", | |
"Andhra Pradesh": "AP", | |
"Arunachal Pradesh": "AR", | |
"Assam": "AS", | |
"Bihar": "BR", | |
"Chandigarh": "CG", | |
"Chhattisgarh": "CH", | |
"Delhi" : "DL", | |
"Goa" : "GA", | |
"Gujarat" : "GJ", | |
"Haryana" : "HR", | |
"Himachal Pradesh" : "HP", | |
"Jammu and Kashmir" : "HK", | |
"Jharkhand" : "JH", | |
"Karnataka" : "KA", | |
"Kerala" : "KL", | |
"Ladakh" : "LD", | |
"Lakshadweep" : "LK", | |
"Madhya Pradesh" : "MP", | |
"Maharashtra" : "MH", | |
"Manipur" : "MN", | |
"Meghalaya" : "MH", | |
"Mizoram" : "MZ", | |
"Nagaland" :"NL", | |
"Odisha" : "OD", | |
"Puducherry" : "PY", | |
"Punjab" : "PB", | |
"Rajasthan" : "RJ", | |
"Tamil Nadu" : "TN", | |
"Telangana" : "TS", | |
"Tripura" : "TR", | |
"Sikkim": "SK", | |
"Uttar Pradesh" : "UP", | |
"Uttarakhand" : "UK", | |
"West Bengal" : "WB", | |
} | |
var log = console.log; | |
const lang = 'en-US'; | |
function dateToTS(date) { | |
return date.valueOf(); | |
} | |
function tsToDate(ts) { | |
const d = new Date(ts); | |
return d.toLocaleDateString(lang, { | |
year: 'numeric', | |
month: 'long', | |
day: 'numeric', | |
}); | |
} | |
function filterData(dt, from, to, formatReq) { | |
// log("--====--", dt, formatReq); | |
if (!formatReq) { | |
dt = dateToTS(new Date(dt)); | |
} | |
else { | |
const parts = dt.split('/'); | |
dt = new Date( | |
parts[1] + '-' + parts[0] + '-' + parts[2].split(' ')[0] | |
); | |
} | |
if (dt >= from && dt <= to) { | |
return true; | |
} | |
console.log("dt::::", dt, from, to); | |
} | |
var daily_conf = dc.lineChart("#daily_conf"); | |
var daily_actv = dc.lineChart("#daily_actv"); | |
var daily_recov = dc.lineChart("#daily_recov"); | |
var daily_dcsd = dc.lineChart("#daily_dcsd"); | |
var composite = dc.compositeChart("#line-chart"); | |
// var composite2 = dc.compositeChart("#line-chart2"); | |
var composite2 = dc.barChart("#line-chart2"); | |
// var dailycase = dc.barChart("#line-chart2"); | |
var linechart = dc.lineChart("#line-chart"); | |
var total_chart = dc.compositeChart("#total_cases"); | |
var total_line_chart = dc.lineChart("#total_cases"); | |
Promise.all([ | |
d3.json("https://api.covid19india.org/data.json"), | |
d3.json("https://api.rootnet.in/covid19-in/unofficial/covid19india.org/statewise/history") | |
]).then(([data1,data2]) => { | |
var data = data1.cases_time_series; | |
var from = new Date(2020,0,31); | |
var to = new Date() | |
var co = 0, count=0; | |
// log("=============:::", data[data.length-1]); | |
for (var start = 0; start <= data.length-1; start++) { | |
var day = new Date(data[start].date+"2020"); | |
// log("day:",day); | |
// date = day.toISOString().slice(0, 10); | |
date = day.toDateString().split(" ") | |
date = date[2]+"-"+date[1]+"-"+date[3] | |
// log("day:", day," date:", date); | |
if (new Date(date)<=new Date('2020-03-14')) | |
{ | |
conf = parseInt(data[co]['totalconfirmed']); | |
recov = parseInt(data[co]['totalrecovered']); | |
dcsd = parseInt(data[co]['totaldeceased']); | |
actv = conf - recov - dcsd; | |
d_conf = parseInt(data[co]['dailyconfirmed']); | |
d_recov = parseInt(data[co]['dailyrecovered']); | |
d_dcsd = parseInt(data[co]['dailydeceased']); | |
d_actv = d_conf - d_recov - d_dcsd; | |
data[co] = {"day":date, "daily_confirmed": d_conf, "daily_recovered": d_recov, "daily_deceased": d_dcsd, "daily_active": d_conf-d_recov-d_dcsd}; | |
data[co]['total'] = {"confirmed": conf, "recovered": recov, "deaths": dcsd, "active":actv }; | |
statewise_arr = new Array(35); | |
for (var st=0; st<35; st++) | |
{ | |
var state_name = Object.keys(map_state)[st]; | |
statewise_arr[st] = ({'state': state_name, "confirmed": 0, "recovered": 0, "deaths": 0, "active": 0}) | |
} | |
data[co]['statewise'] = statewise_arr; | |
count = count + 1; | |
} | |
else | |
{ | |
data_add = data2.data.history[co-count+1]; | |
conf = parseInt(data_add['total'].confirmed); | |
recov = parseInt(data_add['total'].recovered); | |
actv = parseInt(data_add['total'].active); | |
dcsd = parseInt(data_add['total'].deaths); | |
d_conf = parseInt(data[co]['dailyconfirmed']); | |
d_recov = parseInt(data[co]['dailyrecovered']); | |
d_dcsd = parseInt(data[co]['dailydeceased']); | |
d_actv = d_conf - d_recov - d_dcsd; | |
// log("===>:", data_add); | |
data[co] = {"day":date, "daily_confirmed": d_conf, "daily_recovered": d_recov, "daily_deceased": d_dcsd, "daily_active": d_conf-d_recov-d_dcsd}; | |
data[co]['total'] = {"confirmed": conf, "recovered": recov, "deaths": dcsd, "active":actv }; | |
var i =0; | |
statewise_arr = new Array(); | |
for (var st=0; st<data_add['statewise'].length; st++) | |
{ | |
statewise_arr[i] = (data_add['statewise'][st]); | |
i=i+1; | |
} | |
data[co]['statewise'] = statewise_arr; | |
} | |
co = co + 1 ; | |
} | |
// log("####:", data); | |
var latest_data = data[data.length-1]; | |
var dateList = data.map(function (el) { | |
return new Date(el.day); | |
}); | |
// log("--------->", dateList); | |
const startDate = new Date("2020-03-15");//new Date(Math.min.apply(null, dateList)); | |
const endDate = new Date(Math.max.apply(null, dateList)); | |
log("sdate,edate:", startDate, endDate); | |
const saveResult = function (datetime) { | |
const from = datetime['from']; | |
const to = datetime['to']; | |
log("from-to:", from, to); | |
const tsDataSliced = data.filter(function (d) { | |
return filterData(d.day, from, to, false); | |
}); | |
stateline_chart(tsDataSliced); | |
log("sliced_data:", tsDataSliced); | |
return tsDataSliced; | |
}; | |
$('#ui').ionRangeSlider({ | |
skin: 'round', | |
type: 'double', | |
grid: true, | |
min: dateToTS(startDate), | |
max: dateToTS(endDate), | |
from: dateToTS(startDate), | |
to: dateToTS(endDate), | |
prettify: tsToDate, | |
// onStart: function (datatime) { | |
// saveResult(datatime) | |
// }, | |
onChange: saveResult, | |
onFinish: saveResult, | |
}) | |
; | |
data = data.filter(function (d) { | |
return filterData(d.day, dateToTS(startDate), dateToTS(endDate), false); | |
}); | |
stateline_chart(data); | |
// | |
}) | |
.catch(error => log('error', error)) | |
function stateline_chart(data) { | |
// log("--->", data); | |
// var data = json_data.data.history; | |
cf = crossfilter(data); // Main crossfilter objects | |
// log("@@@@@@:", data); | |
var cases_bar_d = cf.dimension(function(d) { | |
// log("===>", d.day); | |
return new Date(d.day)}); | |
var daily_cases_bar_g = cases_bar_d.group().reduce( | |
// add | |
(p, v) => { | |
p['dailyconfirmed'] = v.daily_confirmed || 0; | |
p['dailyrecovered'] = v.daily_recovered || 0; | |
p['dailydeaths'] = v.daily_deceased || 0; | |
p['dailyactive'] = v.daily_active || 0; | |
return p; | |
}, | |
// remove | |
(p, v) => { | |
p['dailyconfirmed'] -= v.daily_confirmed; | |
p['dailyrecovered'] -= v.daily_recovered; | |
p['dailydeaths'] -= v.daily_deceased; | |
p['dailyactive'] -= v.daily_active; | |
return p; | |
}, | |
// init | |
() => ({}) | |
); | |
// log("!@#$:", daily_cases_bar_g.top(Infinity)); | |
var cases_bar_g = cases_bar_d.group().reduce( | |
// add | |
(p, v) => { | |
v.statewise.forEach(({state, confirmed}) => p[state] = (p[state] || 0) + confirmed); | |
return p; | |
}, | |
// remove | |
(p, v) => { | |
v.statewise.forEach(({state, confirmed}) => p[state] -= confirmed); | |
return p; | |
}, | |
// init | |
() => ({}) | |
); | |
var active_cases_bar_g = cases_bar_d.group().reduce( | |
// add | |
(p, v) => { | |
v.statewise.forEach(({state, confirmed, recovered}) => p[state] = (p[state] || 0) + (confirmed - recovered) ); | |
return p; | |
}, | |
// remove | |
(p, v) => { | |
v.statewise.forEach(function({state, confirmed, recovered}) { | |
// log("%%%%%%%%:", state); | |
p[state] -= (confirmed - recovered) | |
}); | |
return p; | |
}, | |
// init | |
() => ({}) | |
); | |
var recovered_cases_bar_g = cases_bar_d.group().reduce( | |
// add | |
(p, v) => { | |
v.statewise.forEach(({state, recovered}) => p[state] = (p[state] || 0) + recovered ); | |
return p; | |
}, | |
// remove | |
(p, v) => { | |
v.statewise.forEach(({state, recovered}) => p[state] -= recovered); | |
return p; | |
}, | |
// init | |
() => ({}) | |
); | |
var death_cases_bar_g = cases_bar_d.group().reduce( | |
// add | |
(p, v) => { | |
v.statewise.forEach(({state, deaths}) => p[state] = (p[state] || 0) + deaths); | |
return p; | |
}, | |
// remove | |
(p, v) => { | |
v.statewise.forEach(({state, deaths}) => p[state] -= deaths); | |
return p; | |
}, | |
// init | |
() => ({}) | |
); | |
var total_cases_bar_g = cases_bar_d.group().reduce( | |
// add | |
(p, v) => { | |
p['totalconfirmed'] = v.total.confirmed || 0; | |
p['totalrecovered'] = v.total.recovered || 0; | |
p['totaldeaths'] = v.total.deaths || 0; | |
p['totalactive'] = v.total.active || 0; | |
return p; | |
}, | |
// remove | |
(p, v) => { | |
p['totalconfirmed'] -= v.total.confirmed; | |
p['totalrecovered'] -= v.total.recovered; | |
p['totaldeaths'] -= v.total.deaths; | |
p['totalactive'] -= v.total.active; | |
return p; | |
}, | |
// init | |
() => ({}) | |
); | |
const states = data[0].statewise.map(d => d.state); | |
var latest_data = data[data.length-1]; | |
var top_states =latest_data.statewise; | |
const dateList = data.map(function (el) { | |
return (el.day); | |
}); | |
function find_max(state, case_type){ | |
var max_case = charts_cases_type[case_type].top(Infinity); | |
var max = 0, val; | |
for (var j=0; j<max_case.length;j++) | |
{ | |
val = max_case[j].value[state]; | |
if (max<=val){ | |
max = val; | |
} | |
} | |
return max; | |
} | |
var color = d3.scaleOrdinal(d3.schemeCategory10); | |
var colorScales =[ | |
d3.scaleOrdinal(d3.schemeCategory10), | |
d3.scaleOrdinal(d3.schemeSet3) | |
]; | |
const sDate = new Date(dateList[0]); | |
const eDate = new Date(dateList[dateList.length-1]); | |
var selected_state="top 10 states", selected_case_type = "confirmed"; | |
var charts_cases_type = {confirmed: cases_bar_g, active: active_cases_bar_g, recovered: recovered_cases_bar_g, deaths: death_cases_bar_g}; | |
$(document).ready( | |
function() { | |
$('#kpi-confirmed .value').text(latest_data.total.confirmed); | |
$('#kpi-confirmed .diff').html("( +"+latest_data.daily_confirmed+" )"); | |
$('#kpi-active .value').text(latest_data.total.active); | |
$('#kpi-active .diff').html("( +"+latest_data.daily_active+" )"); | |
$('#kpi-recovered .value').text(latest_data.total.recovered); | |
$('#kpi-recovered .diff').html("( +"+latest_data.daily_recovered+" )"); | |
$('#kpi-death .value').text(latest_data.total.deaths); | |
$('#kpi-death .diff').html("( +"+latest_data.daily_deceased+" )"); | |
} | |
); | |
// Drew SVG | |
var svg = d3.select("body").append("svg") | |
.attr("width", 500) | |
.attr("height", 230); | |
var width_conf = document.getElementById('kpi-confirmed').offsetWidth*0.85; | |
var height_conf = document.getElementById('kpi-confirmed').offsetHeight*0.60; | |
var width_total = document.getElementsByClassName('column')[0].offsetWidth; | |
var height_total = document.getElementsByClassName('column')[0].offsetHeight*0.85; | |
window.onresize = function(event) { | |
width_conf = document.getElementById("kpi-confirmed").offsetWidth*0.85; | |
height_conf = document.getElementById('kpi-confirmed').offsetHeight*0.55; | |
// log("323232:", width_conf, height_conf); | |
daily_conf.width(width_conf) | |
.height(height_conf); | |
daily_recov.width(width_conf) | |
.height(height_conf); | |
daily_actv.width(width_conf) | |
.height(height_conf); | |
daily_dcsd.width(width_conf) | |
.height(height_conf); | |
}; | |
// log("height::::::", width_conf,width_conf*0.5, height_conf, height_conf*0.7) | |
function dailyconf() | |
{ | |
daily_conf | |
.width(width_conf) | |
.height(height_conf) | |
.margins({top: 0, right: 0, bottom: -1, left: -1}) | |
.transitionDuration(500) | |
.dimension(cases_bar_d) | |
.group(daily_cases_bar_g, "dailyconfirmed") | |
.valueAccessor(function(d) { | |
return d.value['dailyconfirmed'];}) | |
.renderArea(true) | |
.elasticY(true) | |
.elasticX(true) | |
.colors("red") | |
.brushOn(false) | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'), eDate])); | |
return daily_conf; | |
} | |
dailyconf(); | |
function dailyrecov() | |
{ | |
daily_recov.width(width_conf) | |
.height(height_conf) | |
.margins({top: 0, right: 0, bottom: -1, left: -1}) | |
.transitionDuration(500) | |
.dimension(cases_bar_d) | |
.group(daily_cases_bar_g, "dailyrecovered") | |
.valueAccessor(function(d) { | |
return d.value['dailyrecovered'];}) | |
.renderArea(true) | |
.elasticY(true) | |
.elasticX(true) | |
.colors("#389e05") | |
.brushOn(false) | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'), eDate])); | |
} | |
dailyrecov(); | |
function dailyactv() | |
{ | |
daily_actv.width(width_conf) | |
.height(height_conf) | |
.margins({top: 0, right: 0, bottom: -1, left: -1}) | |
.transitionDuration(500) | |
.dimension(cases_bar_d) | |
.group(daily_cases_bar_g, "dailyactive") | |
.valueAccessor(function(d) { | |
return d.value['dailyactive'];}) | |
.renderArea(true) | |
.elasticY(true) | |
.elasticX(true) | |
.colors("#1876d3") | |
.brushOn(false) | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'), eDate])); | |
} | |
dailyactv(); | |
function dailydcsd() | |
{ | |
daily_dcsd.width(width_conf) | |
.height(height_conf) | |
.margins({top: 0, right: 0, bottom: -1, left: -1}) | |
.transitionDuration(500) | |
.dimension(cases_bar_d) | |
.group(daily_cases_bar_g, "dailydeaths") | |
.valueAccessor(function(d) { | |
return d.value['dailydeaths'];}) | |
.renderArea(true) | |
.elasticY(true) | |
.elasticX(true) | |
.colors("#36484f") | |
.brushOn(false) | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'), eDate])); | |
} | |
dailydcsd(); | |
function daily_chart() | |
{ | |
// log("^^^^^^^^^:", daily_cases_bar_g.all().length); | |
composite2 | |
.width(width_total) | |
.height(height_total) | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'),eDate])) | |
.xUnits(function(){ return 100} ) | |
// .xUnits(daily_cases_bar_g.all().length * 0.8) | |
.margins({left: 55, top: 1, right: 30, bottom: 30}) | |
.elasticX(true) | |
.elasticY(true) | |
.brushOn(false) | |
.yAxisLabel("Daily Cases") | |
.dimension(cases_bar_d) | |
.centerBar(true) | |
.ordinalColors(['#389e05', '#36484f', 'red']) | |
.group(daily_cases_bar_g, "dailyrecovered") | |
.valueAccessor(function(d) { | |
return d.value['dailyrecovered']}) | |
.stack(daily_cases_bar_g, "dailydeaths", function(d) {return d.value['dailydeaths'];}) | |
.stack(daily_cases_bar_g, "dailyactive", function(d) {return d.value['dailyactive'];}) | |
.legend(dc.legend().x(75).y(15).gap(5).horizontal(false).legendText(function(d) { | |
return d.name; | |
})); | |
composite2.on('pretransition', function(chart){ | |
chart.xAxis().ticks(8).tickFormat(d3.timeFormat("%d %b")); | |
chart.selectAll("g.x text") | |
.attr('transform', "rotate(30)") | |
.style('text-anchor','start') | |
.style('font-weight','bold'); | |
chart.selectAll("g.y text") | |
.style('font-weight','bold'); | |
}); | |
// composite2.on('preRedraw', function(chart) { | |
// chart.xUnits(chart.group().all().length * 0.8); | |
// }); | |
// composite2.on("preRedraw", function (chart) { | |
// chart.rescale(); | |
// }); | |
} | |
daily_chart(); | |
function daily_cases_type(case_type) | |
{ | |
// log("case_type::::", case_type); | |
var cases_color = {'dailyconfirmed': 'red', 'dailyactive': '#1876d3', 'dailyrecovered': '#389e05', 'dailydeaths': '#36484f'}; | |
composite2 | |
.width(width_total) | |
.height(height_total) | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'),eDate])) | |
.margins({left: 60, top: 1, right: 30, bottom: 30}) | |
// .y(d3.scaleLinear().domain([0,1000])) | |
.brushOn(false) | |
.yAxisLabel("Daily Cases") | |
.dimension(cases_bar_d) | |
.centerBar(true) | |
.elasticX(true) | |
.elasticY(true) | |
.colors(cases_color[case_type]) | |
.group(daily_cases_bar_g, case_type) | |
.valueAccessor(function(d) { | |
return d.value[case_type]}) | |
.legend(dc.legend().x(75).y(15).gap(5).horizontal(false).legendText(function(d) { | |
return d.name; | |
})); | |
composite2.on('pretransition', function(chart){ | |
chart.xAxis().ticks(8).tickFormat(d3.timeFormat("%d %b")); | |
chart.selectAll("g.x text") | |
.attr('transform', "rotate(30)") | |
.style('text-anchor','start') | |
.style('font-weight','bold'); | |
chart.selectAll("g.y text") | |
.style('font-weight','bold'); | |
}); | |
} | |
function total_cases_type(case_type) | |
{ | |
// log("case_type:", case_type); | |
var cases_color = {'totalconfirmed': 'red', 'totalactive': '#1876d3', 'totalrecovered': '#389e05', 'totaldeaths': '#36484f'}; | |
total_line_chart | |
.width(width_total) | |
.height(height_total) | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'),eDate])) | |
.margins({left: 55, top: 1, right: 20, bottom: 30}) | |
// .y(d3.scaleLinear().domain([0,1000])) | |
.brushOn(false) | |
.yAxisLabel("Total Cases") | |
.dimension(cases_bar_d) | |
.colors(cases_color[case_type]) | |
// .centerBar(true) | |
.elasticY(true) | |
.elasticX(true) | |
// .colors(color[case_type]) | |
.group(total_cases_bar_g, case_type) | |
.valueAccessor(function(d) { | |
return d.value[case_type]}) | |
.legend(dc.legend().x(85).y(15).gap(5).horizontal(false).legendText(function(d) { | |
return d.name; | |
})); | |
total_line_chart.on('pretransition', function(chart){ | |
chart.xAxis().ticks(8).tickFormat(d3.timeFormat("%d %b")); | |
chart.selectAll("g.x text") | |
.attr('transform', "rotate(30)") | |
.style('text-anchor','start') | |
.style('font-weight','bold'); | |
chart.selectAll("g.y text") | |
.style('font-weight','bold'); | |
}); | |
} | |
function total_cases_chart() | |
{ | |
// log("------------>", width_total, height_total); | |
total_chart | |
.width(width_total) | |
.height(height_total) | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'),eDate])) | |
.margins({left: 60, top: 1, right: 30, bottom: 30}) | |
.brushOn(false) | |
.yAxisLabel("Total Cases") | |
.dimension(cases_bar_d) | |
.elasticY(true) | |
.elasticX(true) | |
// .xUnits(dc.units.ordinal) | |
.compose([ | |
dc.lineChart(total_chart) | |
.colors("red") | |
.group(total_cases_bar_g, "totalconfirmed") | |
.valueAccessor(function(d) { | |
return d.value['totalconfirmed']}), | |
dc.lineChart(total_chart) | |
.colors("#1876d3") | |
.group(total_cases_bar_g, "totalactive") | |
.valueAccessor(function(d) { | |
return d.value['totalactive']}), | |
dc.lineChart(total_chart) | |
.colors("#389e05") | |
.group(total_cases_bar_g, "totalrecovered") | |
.valueAccessor(function(d) { | |
return d.value['totalrecovered']}), | |
dc.lineChart(total_chart) | |
.colors("#36484f") | |
.group(total_cases_bar_g, "totaldeaths") | |
.valueAccessor(function(d) { | |
return d.value['totaldeaths']}) | |
]) | |
.legend(dc.legend().x(85).y(15).gap(5).horizontal(false).legendText(function(d) { | |
// log("**********:", d); | |
return d.name; | |
})); | |
// total_chart.xAxis().ticks(8).tickFormat(d3.timeFormat("%d %b")) | |
total_chart.on('pretransition', function(chart){ | |
chart.children().forEach( | |
child => child.selectAll('circle.dot') | |
.on('mousemove', null) | |
.on('mouseout', null) | |
); | |
chart.xAxis().ticks(8).tickFormat(d3.timeFormat("%d %b")); | |
chart.selectAll("g.x text") | |
.attr('transform', "rotate(30)") | |
.style('text-anchor','start') | |
.style('font-weight','bold'); | |
chart.selectAll("g.y text") | |
.style('font-weight','bold'); | |
}); | |
// // remove hover events from dots | |
// total_chart.on('pretransition', chart => { | |
// chart.children().forEach( | |
// child => child.selectAll('circle.dot') | |
// .on('mousemove', null) | |
// .on('mouseout', null) | |
// ); | |
// }) | |
total_chart.on('postRender', chart => { | |
chart.svg().on('mousemove', () => { | |
// find closest data point | |
const x = chart.x().invert(d3.mouse(chart.svg().node())[0] - chart.margins().left), | |
xs = chart.children()[0].group().all().map(kv => kv.key), | |
right = d3.bisectLeft(xs, x); | |
// log("xonst x:", x); | |
let closest = right; | |
if(right >= xs.length) | |
closest = right - 1; | |
else if(right > 0) { | |
// see if point to the left is closer | |
if(x - xs[right-1] < xs[right] - x) | |
closest = right - 1; | |
} | |
console.log('closest', new Date(x), closest, xs[closest]); | |
chart.children().forEach(child => { | |
child.g().selectAll('circle.dot').each(function(d) { | |
if(d.x === xs[closest]) { | |
child._showDot(d3.select(this)); | |
child.g().select('text.data-tip') | |
.attr('visibility', 'visible') | |
.attr('x', child.x()(d.x)) | |
.attr('y', child.y()(d.y)) | |
.text(tooltip_text(d.data)) | |
} else | |
log("---->child-->", child); | |
child._hideDot(d3.select(this)); | |
}); | |
}) | |
}) | |
chart.svg().on('mouseout', () => { | |
chart.children().forEach(child => { | |
child.g().select('text.data-tip') | |
.attr('visibility', 'hidden') | |
child.selectAll('circle.dot').each(function(d) { | |
child._hideDot(d3.select(this)); | |
}); | |
}) | |
}) | |
chart.children().forEach(child => child.g() | |
.append('text') | |
.attr('class', 'data-tip') | |
.attr('fill', 'black') | |
.attr('alignment-baseline', 'top') | |
.attr('text-anchor', 'begin') | |
.attr('visibility', 'hidden') | |
) | |
}); | |
// total_chart.yAxis().tickFormat(d3.format("s")); | |
} | |
// total_cases_type('totalconfirmed'); | |
total_cases_chart(); | |
total_chart.render(); | |
function comp_chart_daily(){ | |
var cases = ['dailyconfirmed', 'dailyrecovered', 'dailydeceased'] | |
var cases_color = {'dailyconfirmed': 'red', 'dailyactive': '#1876d3', 'dailyrecovered': '#389e05', 'dailydeaths': '#36484f'}; | |
// cases.map((case_type, i) => log("===>:", case_type, i)); | |
composite2 | |
.width(width_total) | |
.height(height_total) | |
// .ordinalColors(["#7FC97F","#BEAED4",'#FDC086']) | |
.x(d3.scaleTime().domain([sDate,eDate])) | |
.yAxisLabel("This is the Y Axis!") | |
.legend(dc.legend().x(70).y(40).itemHeight(13).gap(5)) | |
.renderHorizontalGridLines(true) | |
.dimension(cases_bar_d) | |
.elasticX(true) | |
.elasticY(true) | |
.brushOn(false) | |
.shareTitle(false) | |
.compose(cases.map( | |
(case_type,i) => dc.lineChart(composite) | |
.dimension(cases_bar_d) | |
// .colors(cases_color[case_type]) | |
.group(daily_cases_bar_g, "dailyconfirmed") | |
.valueAccessor(function(d) { | |
return d.value['dailyconfirmed']; }) | |
)); | |
composite.on('pretransition', function(chart){ | |
chart.xAxis().ticks(8).tickFormat(d3.timeFormat("%d %b")); | |
chart.selectAll("g.x text") | |
.attr('transform', "rotate(30)") | |
.style('text-anchor','start') | |
.style('font-weight','bold'); | |
chart.selectAll("g.y text") | |
.style('font-weight','bold'); | |
}); | |
composite | |
.on('pretransition.hideshow', legendToggle); | |
}; | |
function comp_chart(case_type){ | |
top_states_res = top_states.sort(function(a, b) { | |
return b[case_type] - a[case_type]; | |
}).slice(0,10).map(d => d.state); | |
var max_cases = find_max(top_states_res[0], case_type) | |
composite | |
.width(width_total) | |
.height(height_total) | |
.margins({left: 55, top: 1, right: 20, bottom: 30}) | |
.yAxisLabel("Total Cases") | |
.x(d3.scaleTime().domain([new Date('15 Mar 2020'),eDate])) | |
.y(d3.scaleLinear().domain([0,max_cases*1.1])) | |
.xUnits(d3.timeDays()) | |
.legend(dc.legend().x(85).y(15).itemHeight(13).gap(5)) | |
.renderHorizontalGridLines(true) | |
.brushOn(false) | |
.elasticX(true) | |
.elasticY(true) | |
.shareTitle(false) | |
.compose(top_states_res.map( | |
(state,i) => dc.lineChart(composite) | |
.dimension(cases_bar_d) | |
.group(charts_cases_type[case_type], state) | |
.valueAccessor(kv => kv.value[state]) | |
.colors(colorScales[0] | |
(Math.random())) | |
.x(d3.scaleTime().domain([sDate,eDate])) | |
.title(function(d) { return (d.key.toDateString() + "\n" + state + ': ' + d.value[state]) }) | |
)); | |
composite.on('pretransition', function(chart){ | |
chart.xAxis().ticks(8).tickFormat(d3.timeFormat("%d %b")); | |
chart.selectAll("g.x text") | |
.attr('transform', "rotate(30)") | |
.style('text-anchor','start') | |
.style('font-weight','bold'); | |
chart.selectAll("g.y text") | |
.style('font-weight','bold'); | |
}); | |
composite | |
.on('pretransition.hideshow', legendToggle); | |
}; | |
function line_chart(state, case_type){ | |
var cases_color = {'confirmed': 'red', 'active': '#1876d3', 'recovered': '#389e05', 'deaths': '#36484f'}; | |
var state_cases = find_max(state, case_type) | |
linechart | |
.width(width_total) | |
.height(height_total) | |
.margins({left: 65, top: 1, right: 20, bottom: 30}) | |
.dimension(cases_bar_d) | |
.group(charts_cases_type[case_type], state) | |
.valueAccessor(kv => kv.value[state]) | |
.colors(cases_color[case_type]) | |
.yAxisLabel("Total Cases") | |
.legend(dc.legend().x(80).y(15).itemHeight(13).gap(5)) | |
.x(d3.scaleTime().domain([sDate,eDate])) | |
.y(d3.scaleLinear().domain([0,state_cases*1.1])) | |
.xUnits(d3.timeDays()) | |
.title(function(d) { return (d.key.toDateString() + "\n" + state + ': ' + d.value[state]) }) | |
.renderHorizontalGridLines(true) | |
.brushOn(false) | |
.elasticX(true) | |
.elasticY(true) | |
linechart.on('pretransition', function(chart){ | |
chart.xAxis().ticks(8).tickFormat(d3.timeFormat("%d %b")); | |
chart.selectAll("g.x text") | |
.attr('transform', "rotate(30)") | |
.style('text-anchor','start') | |
.style('font-weight','bold'); | |
chart.selectAll("g.y text") | |
.style('font-weight','bold'); | |
}); | |
} | |
function drawLegendToggles(chart) { | |
chart.selectAll('g.dc-legend .dc-legend-item') | |
.style('opacity', function(d, i) { | |
var subchart = chart.select('g.sub._' + i); | |
var visible = subchart.style('visibility') !== 'hidden'; | |
return visible ? 1 : 0.2; | |
}); | |
} | |
function legendToggle(chart) { | |
chart.selectAll('g.dc-legend .dc-legend-item') | |
.on('click.hideshow', function(d, i) { | |
var subchart = chart.select('g.sub._' + i); | |
var visible = subchart.style('visibility') !== 'hidden'; | |
subchart.style('visibility', function() { | |
return visible ? 'hidden' : 'visible'; | |
}); | |
drawLegendToggles(chart); | |
}) | |
drawLegendToggles(chart); | |
} | |
comp_chart(selected_case_type); | |
d3.selectAll('.kpi-box')//.select("kpi-confirmed") | |
.on('click', function() { | |
// log("%%%%%%%%:",this, d3.select(this).attr('value')); | |
d3.selectAll('.kpi-box').each(function() { | |
// log("->:",$(this)) | |
$(this).css({ | |
"box-shadow": "0px 2px 4px 0px rgba(0,0,0,0.2)" | |
}); | |
}) | |
$(this).css({ | |
"box-shadow": "inset 0 1px 1px #dab6b6, 0 0 8px #da0707" | |
}); | |
var ctype = d3.select(this).attr('value'); | |
// log("ctype:" ,ctype); | |
selected_case_type = ctype; | |
daily_cases_type("daily"+ctype); | |
composite2.render(); | |
total_cases_type("total"+ctype); | |
total_line_chart.margins({left: 70, top: 1, right: 30, bottom: 30}) | |
total_line_chart.render(); | |
switch(selected_state) | |
{ | |
case "top 10 states": | |
{ | |
var div = d3.selectAll("g.sub"); | |
div.style("display","none"); | |
comp_chart(ctype); | |
composite.margins({left: 65, top: 1, right: 20, bottom: 30}) | |
composite.render(); | |
break; | |
} | |
default: | |
{ | |
line_chart(selected_state, ctype); | |
linechart.render(); | |
} | |
} | |
}); | |
var intervals = {"Top 10 states" : "top 10 states"}; | |
states.forEach(function (state, index){ | |
intervals[state] = state; | |
}); | |
var defint = 'Top 10 states'; | |
d3.select('#interval').selectAll('option') | |
.data(Object.keys(intervals)) | |
.enter().append('option') | |
.text(function(d) { return d; }) | |
.attr('selected', function(d) { return d === defint ? '' : null; }); | |
function setup() { | |
var start_t = window.performance.now(); | |
var interval_name = d3.select('#interval').nodes()[0].value; | |
var interval = intervals[interval_name]; | |
selected_state = interval; | |
switch(interval_name) { | |
case 'Top 10 states': | |
comp_chart(selected_case_type); | |
composite.render(); | |
break; | |
default: | |
line_chart(interval_name, selected_case_type); | |
linechart.margins({left: 65, top: 1, right: 20, bottom: 30}) | |
linechart.render(); | |
break; | |
} | |
}; | |
d3.select('#interval').on('change', function() { | |
setup(); | |
}); | |
dc.renderAll(); | |
return ; | |
}; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment