Skip to content

Instantly share code, notes, and snippets.

@gordonwoodhull
Last active May 26, 2020 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gordonwoodhull/c3e6be61aec3ebcce4976ce6d86674a9 to your computer and use it in GitHub Desktop.
Save gordonwoodhull/c3e6be61aec3ebcce4976ce6d86674a9 to your computer and use it in GitHub Desktop.
2_graphs
license: mit
<!DOCTYPE html>
<head>
<!-- <title>Test-Dashboard</title> -->
<style>
line {
stroke: #000000;
stroke-width: 1.5;
}
#interval {
float: right;
/* position: absolute; */
}
select
{
/*color: #ccc;*/
}
option
{
color: #000;
}
option:first-child
{
background-color: #bdbdff;
}
</style>
<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>
<!-- column 3 for row -->
<div class="col-lg-6 col-md-6">
<!-- row in column 3 -->
<div class="row">
<!-- Bar Chart -->
<div class="col-lg-12 col-md-12">
<div class="chart-wrapper">
<div class="chart-stage">
<div id="select-operation">
<label><input type=radio name="operation" value="Confirmed" checked="true">&nbsp;Confirmed</label>
<label><input type=radio name="operation" value="Active">&nbsp;Active</label>
<label><input type=radio name="operation" value="Recovered">&nbsp;Recovered</label>
<label><input type=radio name="operation" value="Death">&nbsp;Death</label>
</div>
<div id="line-chart" class="svg-container">
<select id="interval"></select>
<div class="chart-title">
<span>
<strong>Line Types</strong>
</span>
<span>
<a href="javascript:composite.filterAll(); dc.redrawAll();" style="display:none;" class="reset">reset</a>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-6 col-md-6">
<!-- row in column 3 -->
<div class="row">
<!-- Bar Chart -->
<div class="col-lg-12 col-md-12">
<div class="chart-wrapper">
<div class="chart-stage">
<div id="line-chart2" class="svg-container">
<select id="interval"></select>
<div class="chart-title">
<span>
<strong>Line Types</strong>
</span>
<span>
<a href="javascript:composite.filterAll(); dc.redrawAll();" style="display:none;" class="reset">reset</a>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<body>
<script type="text/javascript" src="http://d3js.org/queue.v1.min.js"></script>
<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",
}
// "Daman and Diu" : "DD",
// "Dadra and Nagar Haveli" : "DN",
var log = console.log;
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;
// data = data.slice(0,-1);
// log("data:", data2);
// data2 = data2.slice(0,-1);
var from = new Date(2020,0,31);
var to = new Date()
// to.setDate(to.getDate() + 1)
// var to = new Date();
var co = 0, count=0;
for (var day = from; day <= to; day.setDate(day.getDate() + 1)) {
date = day.toISOString().slice(0, 10);
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];
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;
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 ;
}
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
var cases_bar_d = cf.dimension(function(d) {
return new Date(d.day)});
var total_cases_bar_g = cases_bar_d.group().reduce(
// add
(p, v) => {
p['dailyconfirmed'] = v.daily_confirmed || 0;
p['dailyrecovered'] = v.daily_recovered || 0;
p['dailydeceased'] = 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['dailydeceased'] -= v.daily_deceased;
p['dailyactive'] -= v.daily_active;
return p;
},
// init
() => ({})
);
log("!@#$:", total_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}) {
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
() => ({})
);
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};
var composite = dc.compositeChart("#line-chart");
var composite2 = dc.barChart("#line-chart2");
var linechart = dc.lineChart("#line-chart")
// var latest_data = data[data.length-1];
// log("latest_data:", latest_data);
// var top_states =latest_data.statewise;
composite2
.width(768)
.height(480)
.x(d3.scaleTime().domain([sDate,eDate]))
// .brushOn(false)
.yAxisLabel("This is the Y Axis!")
.dimension(cases_bar_d)
.group(total_cases_bar_g, "dailyconfirmed")
.valueAccessor(function(d) {
return d.value['dailyconfirmed']; })
composite2.render();
// log("##########:", top_states);
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(500)
.height(460)
.margins({left: 60, top: 20, right: 10, bottom: 100})
.x(d3.scaleTime().domain([sDate,eDate]))
.y(d3.scaleLinear().domain([0,max_cases+100]))
.xUnits(d3.timeDays())
.legend(dc.legend().x(70).y(40).itemHeight(13).gap(5))
.renderHorizontalGridLines(true)
.brushOn(false)
.shareTitle(false)
.compose(top_states_res.map(
(state,i) => dc.lineChart(composite)
.dimension(cases_bar_d)
.group(charts_cases_type[case_type], state)
// .x(d3.scaleTime().domain([sDate,eDate]))
.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.renderlet(function(chart){
chart.selectAll("g.x text")
.attr('transform', "rotate(30)")
.style('text-anchor','start')
.style('font-weight','bold');
});
composite
.on('pretransition.hideshow', legendToggle);
};
function line_chart(state, case_type){
var state_cases = find_max(state, case_type)
linechart
.width(500)
.height(460)
.margins({left: 60, top: 20, right: 10, bottom: 100})
.dimension(cases_bar_d)
.group(charts_cases_type[case_type], state)
.valueAccessor(kv => kv.value[state])
.colors(colorScales[0]
(Math.random()))
.legend(dc.legend().x(70).y(40).itemHeight(13).gap(5))
.x(d3.scaleTime().domain([sDate,eDate]))
.y(d3.scaleLinear().domain([0,state_cases]))
.title(function(d) { return (d.key.toDateString() + "\n" + state + ': ' + d.value[state]) })
.renderHorizontalGridLines(true)
.brushOn(false)
}
function drawLegendToggles(chart) {
const legItem = chart.selectAll('g.dc-legend .dc-legend-item');
if(!legItem) return
legItem
.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) {
const legItem = chart.selectAll('g.dc-legend .dc-legend-item');
if(!legItem) return
legItem
.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);
var accessors = {
Confirmed: "confirmed",
Active: "active",
Recovered: "recovered",
Death: "deaths",
};
d3.selectAll('#select-operation input')
.on('click', function() {
var ctype = accessors[this.value];
selected_case_type = ctype;
switch(selected_state)
{
case "top 10 states":
{
var div = d3.selectAll("g.sub");
div.style("display","none");
comp_chart(ctype);
composite.redraw();
break;
}
default:
{
line_chart(selected_state, ctype);
linechart.redraw();
// break;
}
}
});
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();
// dc.renderAll();
break;
default:
line_chart(interval_name, selected_case_type);
linechart.render();
// dc.renderAll();
break;
}
};
d3.select('#interval').on('change', function() {
setup();
});
dc.renderAll();
};
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment