Close Editor Run Reset Auto Update CJS /*
* COVID-19 Bar chart race on LightningChartJS.
*/
// Import LightningChartJS
const lcjs = require('@lightningchart/lcjs')
// Extract required parts from LightningChartJS.
const { lightningChart, BarChartTypes, AutoCursorModes, AxisTickStrategies, FormattingFunctions, Themes } = lcjs
let initday = 15
let lastDay = new Date('November 15, 2022').toISOString()
let connectionError = ''
const lc = lightningChart()
const barChart = lc
.BarChart({
legend: { visible: false },
type: BarChartTypes.Horizontal,
// theme: Themes.darkGold
})
.setTitle('COVID-19 cases ' + new Date(2020, 2, 15).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' }))
.setCursorMode(undefined)
.setAnimationCategoryPosition(true, 2)
.setAnimationValues(true, 1)
.setPadding({ left: 10, right: 48, top: 10, bottom: 10 })
.setValueLabels({
position: 'inside-bar'
})
barChart.valueAxis
.setTickStrategy(AxisTickStrategies.Numeric, (ticks) => ticks.setFormattingFunction(FormattingFunctions.NumericUnits))
.setAnimationScroll(true)
// Keep track of country colors so they don't change randomly as top 20 displayed countries change over time.
const countryFillStyleCache = new Map()
const theme = barChart.getTheme()
const fillStylePalette =
typeof theme.rectangleSeriesFillStyle === 'function' ? theme.rectangleSeriesFillStyle : () => theme.rectangleSeriesFillStyle
// Loop for adding bars
const addCountries = (entries) => {
barChart.setData(entries.map((item) => ({ category: item.country, value: item.value })))
barChart.getBars().forEach((bar) => {
const fill = countryFillStyleCache.get(bar.category) || fillStylePalette(countryFillStyleCache.size)
countryFillStyleCache.set(bar.category, fill)
bar.setFillStyle(fill)
})
}
// Sorting and splicing array of data
const sortCountries = (data, raceDay) => {
let myday = raceDay.getMonth() + 1 + '/' + raceDay.getDate() + '/' + raceDay.getFullYear().toString().substr(-2)
const countries = { ...data }
// Map list of countries and sort them in the order (First sort by value, then by country)
const countryList = Object.values(countries)
.map((c) => ({ country: c.country, value: c.history[myday] }))
.sort((a, b) => (a.value > b.value ? 1 : a.value === b.value ? (a.country > b.country ? 1 : -1) : -1))
// Keep only top x countries
const displayCount = 20
countryList.splice(0, countryList.length - displayCount)
return countryList
}
// Loop for re-rendering list of data
const startRace = (data) => {
// Inital day of race
let raceDay = new Date(2020, 2, initday)
// Set title of chart
barChart.setTitle(
connectionError + ' COVID-19 cases ' + raceDay.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' }),
)
const sortedCountries = sortCountries(data, raceDay)
addCountries(sortedCountries)
// we've bot reached the last day (i.e. yesterday) execute the function again and increase the day
if (raceDay.toISOString() !== lastDay) {
initday++
setTimeout(() => startRace(data), 100)
}
}
const startRaceHandler = () => {
// Fetch all countries and history of cases
fetch('https://lightningchart.com/lightningchart-js-interactive-examples/data/covid/confirmed.json')
.then((res) => res.json())
.then((data) => {
const dat = [...data.locations]
// After fetching and merging data create bars
startRace(mergeData(dat))
})
.catch((err) => {
lastDay = '2020-05-30T21:00:00.000Z'
connectionError = 'Example of data'
startRace(mergeData(fallbackData))
})
// Some countries are divided by region and it is needed to megre them
const mergeData = (data) => {
const result = []
// Return only specific information
data.forEach((basket) => {
let ob = {
country: basket['country'],
history: { ...basket['history'] },
}
// Check if array already contains the country
let has = false
result.find((obj) => (obj.country == ob.country ? (has = true) : (has = false)))
// Unite object values
const sum = (obj, newObj) => {
Object.keys(obj).map((date) => (obj[date] += newObj[date]))
}
// Format the data
if (has) {
result.find((obj) => obj.country == ob.country && sum(obj.history, ob.history))
} else {
result.push(ob)
}
})
return result
}
}
// Start fetching
startRaceHandler(barChart)
//fallback data
const fallbackData = [
{
country: 'US',
history: {
'3/15/20': 3212,
'3/16/20': 4679,
'3/17/20': 6512,
'3/18/20': 9169,
'3/19/20': 13663,
'3/20/20': 20030,
'3/21/20': 26025,
'3/22/20': 34855,
'3/23/20': 46086,
'3/24/20': 56698,
'3/25/20': 68773,
'3/26/20': 86613,
'3/27/20': 105293,
'3/28/20': 124900,
'3/29/20': 143779,
'3/30/20': 165861,
'3/31/20': 192177,
'4/1/20': 224418,
'4/2/20': 256636,
'4/3/20': 288906,
'4/4/20': 321318,
'4/5/20': 351203,
'4/6/20': 382613,
'4/7/20': 413382,
'4/8/20': 444580,
'4/9/20': 480534,
'4/10/20': 514942,
'4/11/20': 544119,
'4/12/20': 571400,
'4/13/20': 598310,
'4/14/20': 627082,
'4/15/20': 652513,
'4/16/20': 682548,
'4/17/20': 715267,
'4/18/20': 743223,
'4/19/20': 769416,
'4/20/20': 799212,
'4/21/20': 825046,
'4/22/20': 853818,
'4/23/20': 887386,
'4/24/20': 919658,
'4/25/20': 950100,
'4/26/20': 976680,
'4/27/20': 1000298,
'4/28/20': 1024746,
'4/29/20': 1051136,
'4/30/20': 1080303,
'5/1/20': 1115219,
'5/2/20': 1142639,
'5/3/20': 1167095,
'5/4/20': 1191071,
'5/5/20': 1215543,
'5/6/20': 1240053,
'5/7/20': 1267418,
'5/8/20': 1294224,
'5/9/20': 1319414,
'5/10/20': 1338381,
'5/11/20': 1357566,
'5/12/20': 1380423,
'5/13/20': 1400812,
'5/14/20': 1427725,
'5/15/20': 1452425,
'5/16/20': 1476586,
'5/17/20': 1495068,
'5/18/20': 1517302,
'5/19/20': 1538241,
'5/20/20': 1560975,
'5/21/20': 1586662,
'5/22/20': 1610252,
'5/23/20': 1631496,
'5/24/20': 1651676,
'5/25/20': 1670442,
'5/26/20': 1689948,
'5/27/20': 1708342,
'5/28/20': 1730551,
'5/29/20': 1755010,
'5/30/20': 1778689,
'5/31/20': 1797763,
},
},
{
country: 'Russia',
history: {
'3/15/20': 63,
'3/16/20': 90,
'3/17/20': 114,
'3/18/20': 147,
'3/19/20': 199,
'3/20/20': 253,
'3/21/20': 306,
'3/22/20': 367,
'3/23/20': 438,
'3/24/20': 495,
'3/25/20': 658,
'3/26/20': 840,
'3/27/20': 1036,
'3/28/20': 1264,
'3/29/20': 1534,
'3/30/20': 1836,
'3/31/20': 2337,
'4/1/20': 2777,
'4/2/20': 3548,
'4/3/20': 4149,
'4/4/20': 4731,
'4/5/20': 5389,
'4/6/20': 6343,
'4/7/20': 7497,
'4/8/20': 8672,
'4/9/20': 10131,
'4/10/20': 11917,
'4/11/20': 13584,
'4/12/20': 15770,
'4/13/20': 18328,
'4/14/20': 21102,
'4/15/20': 24490,
'4/16/20': 27938,
'4/17/20': 32008,
'4/18/20': 36793,
'4/19/20': 42853,
'4/20/20': 47121,
'4/21/20': 52763,
'4/22/20': 57999,
'4/23/20': 62773,
'4/24/20': 68622,
'4/25/20': 74588,
'4/26/20': 80949,
'4/27/20': 87147,
'4/28/20': 93558,
'4/29/20': 99399,
'4/30/20': 106498,
'5/1/20': 114431,
'5/2/20': 124054,
'5/3/20': 134687,
'5/4/20': 145268,
'5/5/20': 155370,
'5/6/20': 165929,
'5/7/20': 177160,
'5/8/20': 187859,
'5/9/20': 198676,
'5/10/20': 209688,
'5/11/20': 221344,
'5/12/20': 232243,
'5/13/20': 242271,
'5/14/20': 252245,
'5/15/20': 262843,
'5/16/20': 272043,
'5/17/20': 281752,
'5/18/20': 290678,
'5/19/20': 299941,
'5/20/20': 308705,
'5/21/20': 317554,
'5/22/20': 326448,
'5/23/20': 335882,
'5/24/20': 344481,
'5/25/20': 353427,
'5/26/20': 362342,
'5/27/20': 370680,
'5/28/20': 379051,
'5/29/20': 387623,
'5/30/20': 396575,
'5/31/20': 405843,
},
},
{
country: 'Spain',
history: {
'3/15/20': 7798,
'3/16/20': 9942,
'3/17/20': 11748,
'3/18/20': 13910,
'3/19/20': 17963,
'3/20/20': 20410,
'3/21/20': 25374,
'3/22/20': 28768,
'3/23/20': 35136,
'3/24/20': 39885,
'3/25/20': 49515,
'3/26/20': 57786,
'3/27/20': 65719,
'3/28/20': 73235,
'3/29/20': 80110,
'3/30/20': 87956,
'3/31/20': 95923,
'4/1/20': 104118,
'4/2/20': 112065,
'4/3/20': 119199,
'4/4/20': 126168,
'4/5/20': 131646,
'4/6/20': 136675,
'4/7/20': 141942,
'4/8/20': 148220,
'4/9/20': 153222,
'4/10/20': 158273,
'4/11/20': 163027,
'4/12/20': 166831,
'4/13/20': 170099,
'4/14/20': 172541,
'4/15/20': 177644,
'4/16/20': 184948,
'4/17/20': 190839,
'4/18/20': 191726,
'4/19/20': 198674,
'4/20/20': 200210,
'4/21/20': 204178,
'4/22/20': 208389,
'4/23/20': 213024,
'4/24/20': 202990,
'4/25/20': 205905,
'4/26/20': 207634,
'4/27/20': 209465,
'4/28/20': 210773,
'4/29/20': 212917,
'4/30/20': 213435,
'5/1/20': 215216,
'5/2/20': 216582,
'5/3/20': 217466,
'5/4/20': 218011,
'5/5/20': 219329,
'5/6/20': 220325,
'5/7/20': 221447,
'5/8/20': 222857,
'5/9/20': 223578,
'5/10/20': 224350,
'5/11/20': 227436,
'5/12/20': 228030,
'5/13/20': 228691,
'5/14/20': 229540,
'5/15/20': 230183,
'5/16/20': 230698,
'5/17/20': 230698,
'5/18/20': 231606,
'5/19/20': 232037,
'5/20/20': 232555,
'5/21/20': 233037,
'5/22/20': 234824,
'5/23/20': 235290,
'5/24/20': 235772,
'5/25/20': 235400,
'5/26/20': 236259,
'5/27/20': 236259,
'5/28/20': 237906,
'5/29/20': 238564,
'5/30/20': 239228,
'5/31/20': 239479,
},
},
{
country: 'Turkey',
history: {
'3/15/20': 6,
'3/16/20': 18,
'3/17/20': 47,
'3/18/20': 98,
'3/19/20': 192,
'3/20/20': 359,
'3/21/20': 670,
'3/22/20': 1236,
'3/23/20': 1529,
'3/24/20': 1872,
'3/25/20': 2433,
'3/26/20': 3629,
'3/27/20': 5698,
'3/28/20': 7402,
'3/29/20': 9217,
'3/30/20': 10827,
'3/31/20': 13531,
'4/1/20': 15679,
'4/2/20': 18135,
'4/3/20': 20921,
'4/4/20': 23934,
'4/5/20': 27069,
'4/6/20': 30217,
'4/7/20': 34109,
'4/8/20': 38226,
'4/9/20': 42282,
'4/10/20': 47029,
'4/11/20': 52167,
'4/12/20': 56956,
'4/13/20': 61049,
'4/14/20': 65111,
'4/15/20': 69392,
'4/16/20': 74193,
'4/17/20': 78546,
'4/18/20': 82329,
'4/19/20': 86306,
'4/20/20': 90980,
'4/21/20': 95591,
'4/22/20': 98674,
'4/23/20': 101790,
'4/24/20': 104912,
'4/25/20': 107773,
'4/26/20': 110130,
'4/27/20': 112261,
'4/28/20': 114653,
'4/29/20': 117589,
'4/30/20': 120204,
'5/1/20': 122392,
'5/2/20': 124375,
'5/3/20': 126045,
'5/4/20': 127659,
'5/5/20': 129491,
'5/6/20': 131744,
'5/7/20': 133721,
'5/8/20': 135569,
'5/9/20': 137115,
'5/10/20': 138657,
'5/11/20': 139771,
'5/12/20': 141475,
'5/13/20': 143114,
'5/14/20': 144749,
'5/15/20': 146457,
'5/16/20': 148067,
'5/17/20': 149435,
'5/18/20': 150593,
'5/19/20': 151615,
'5/20/20': 152587,
'5/21/20': 153548,
'5/22/20': 154500,
'5/23/20': 155686,
'5/24/20': 156827,
'5/25/20': 157814,
'5/26/20': 158762,
'5/27/20': 159797,
'5/28/20': 160979,
'5/29/20': 162120,
'5/30/20': 163103,
'5/31/20': 163942,
},
},
{
country: 'Germany',
history: {
'3/15/20': 5795,
'3/16/20': 7272,
'3/17/20': 9257,
'3/18/20': 12327,
'3/19/20': 15320,
'3/20/20': 19848,
'3/21/20': 22213,
'3/22/20': 24873,
'3/23/20': 29056,
'3/24/20': 32986,
'3/25/20': 37323,
'3/26/20': 43938,
'3/27/20': 50871,
'3/28/20': 57695,
'3/29/20': 62095,
'3/30/20': 66885,
'3/31/20': 71808,
'4/1/20': 77872,
'4/2/20': 84794,
'4/3/20': 91159,
'4/4/20': 96092,
'4/5/20': 100123,
'4/6/20': 103374,
'4/7/20': 107663,
'4/8/20': 113296,
'4/9/20': 118181,
'4/10/20': 122171,
'4/11/20': 124908,
'4/12/20': 127854,
'4/13/20': 130072,
'4/14/20': 131359,
'4/15/20': 134753,
'4/16/20': 137698,
'4/17/20': 141397,
'4/18/20': 143342,
'4/19/20': 145184,
'4/20/20': 147065,
'4/21/20': 148291,
'4/22/20': 150648,
'4/23/20': 153129,
'4/24/20': 154999,
'4/25/20': 156513,
'4/26/20': 157770,
'4/27/20': 158758,
'4/28/20': 159912,
'4/29/20': 161539,
'4/30/20': 163009,
'5/1/20': 164077,
'5/2/20': 164967,
'5/3/20': 165664,
'5/4/20': 166152,
'5/5/20': 167007,
'5/6/20': 168162,
'5/7/20': 169430,
'5/8/20': 170588,
'5/9/20': 171324,
'5/10/20': 171879,
'5/11/20': 172576,
'5/12/20': 173171,
'5/13/20': 174098,
'5/14/20': 174478,
'5/15/20': 175233,
'5/16/20': 175752,
'5/17/20': 176369,
'5/18/20': 176551,
'5/19/20': 177778,
'5/20/20': 178473,
'5/21/20': 179021,
'5/22/20': 179710,
'5/23/20': 179986,
'5/24/20': 180328,
'5/25/20': 180600,
'5/26/20': 181200,
'5/27/20': 181524,
'5/28/20': 182196,
'5/29/20': 182922,
'5/30/20': 183189,
'5/31/20': 183410,
},
},
{
country: 'Brazil',
history: {
'3/15/20': 162,
'3/16/20': 200,
'3/17/20': 321,
'3/18/20': 372,
'3/19/20': 621,
'3/20/20': 793,
'3/21/20': 1021,
'3/22/20': 1546,
'3/23/20': 1924,
'3/24/20': 2247,
'3/25/20': 2554,
'3/26/20': 2985,
'3/27/20': 3417,
'3/28/20': 3904,
'3/29/20': 4256,
'3/30/20': 4579,
'3/31/20': 5717,
'4/1/20': 6836,
'4/2/20': 8044,
'4/3/20': 9056,
'4/4/20': 10360,
'4/5/20': 11130,
'4/6/20': 12161,
'4/7/20': 14034,
'4/8/20': 16170,
'4/9/20': 18092,
'4/10/20': 19638,
'4/11/20': 20727,
'4/12/20': 22192,
'4/13/20': 23430,
'4/14/20': 25262,
'4/15/20': 28320,
'4/16/20': 30425,
'4/17/20': 33682,
'4/18/20': 36658,
'4/19/20': 38654,
'4/20/20': 40743,
'4/21/20': 43079,
'4/22/20': 45757,
'4/23/20': 50036,
'4/24/20': 54043,
'4/25/20': 59324,
'4/26/20': 63100,
'4/27/20': 67446,
'4/28/20': 73235,
'4/29/20': 79685,
'4/30/20': 87187,
'5/1/20': 92202,
'5/2/20': 97100,
'5/3/20': 101826,
'5/4/20': 108620,
'5/5/20': 115455,
'5/6/20': 126611,
'5/7/20': 135773,
'5/8/20': 146894,
'5/9/20': 156061,
'5/10/20': 162699,
'5/11/20': 169594,
'5/12/20': 178214,
'5/13/20': 190137,
'5/14/20': 203165,
'5/15/20': 220291,
'5/16/20': 233511,
'5/17/20': 241080,
'5/18/20': 255368,
'5/19/20': 271885,
'5/20/20': 291579,
'5/21/20': 310087,
'5/22/20': 330890,
'5/23/20': 347398,
'5/24/20': 363211,
'5/25/20': 374898,
'5/26/20': 391222,
'5/27/20': 411821,
'5/28/20': 438238,
'5/29/20': 465166,
'5/30/20': 498440,
'5/31/20': 514849,
},
},
{
country: 'Italy',
history: {
'3/15/20': 24747,
'3/16/20': 27980,
'3/17/20': 31506,
'3/18/20': 35713,
'3/19/20': 41035,
'3/20/20': 47021,
'3/21/20': 53578,
'3/22/20': 59138,
'3/23/20': 63927,
'3/24/20': 69176,
'3/25/20': 74386,
'3/26/20': 80589,
'3/27/20': 86498,
'3/28/20': 92472,
'3/29/20': 97689,
'3/30/20': 101739,
'3/31/20': 105792,
'4/1/20': 110574,
'4/2/20': 115242,
'4/3/20': 119827,
'4/4/20': 124632,
'4/5/20': 128948,
'4/6/20': 132547,
'4/7/20': 135586,
'4/8/20': 139422,
'4/9/20': 143626,
'4/10/20': 147577,
'4/11/20': 152271,
'4/12/20': 156363,
'4/13/20': 159516,
'4/14/20': 162488,
'4/15/20': 165155,
'4/16/20': 168941,
'4/17/20': 172434,
'4/18/20': 175925,
'4/19/20': 178972,
'4/20/20': 181228,
'4/21/20': 183957,
'4/22/20': 187327,
'4/23/20': 189973,
'4/24/20': 192994,
'4/25/20': 195351,
'4/26/20': 197675,
'4/27/20': 199414,
'4/28/20': 201505,
'4/29/20': 203591,
'4/30/20': 205463,
'5/1/20': 207428,
'5/2/20': 209328,
'5/3/20': 210717,
'5/4/20': 211938,
'5/5/20': 213013,
'5/6/20': 214457,
'5/7/20': 215858,
'5/8/20': 217185,
'5/9/20': 218268,
'5/10/20': 219070,
'5/11/20': 219814,
'5/12/20': 221216,
'5/13/20': 222104,
'5/14/20': 223096,
'5/15/20': 223885,
'5/16/20': 224760,
'5/17/20': 225435,
'5/18/20': 225886,
'5/19/20': 226699,
'5/20/20': 227364,
'5/21/20': 228006,
'5/22/20': 228658,
'5/23/20': 229327,
'5/24/20': 229858,
'5/25/20': 230158,
'5/26/20': 230555,
'5/27/20': 231139,
'5/28/20': 231732,
'5/29/20': 232248,
'5/30/20': 232664,
'5/31/20': 232997,
},
},
{
country: 'India',
history: {
'3/15/20': 113,
'3/16/20': 119,
'3/17/20': 142,
'3/18/20': 156,
'3/19/20': 194,
'3/20/20': 244,
'3/21/20': 330,
'3/22/20': 396,
'3/23/20': 499,
'3/24/20': 536,
'3/25/20': 657,
'3/26/20': 727,
'3/27/20': 887,
'3/28/20': 987,
'3/29/20': 1024,
'3/30/20': 1251,
'3/31/20': 1397,
'4/1/20': 1998,
'4/2/20': 2543,
'4/3/20': 2567,
'4/4/20': 3082,
'4/5/20': 3588,
'4/6/20': 4778,
'4/7/20': 5311,
'4/8/20': 5916,
'4/9/20': 6725,
'4/10/20': 7598,
'4/11/20': 8446,
'4/12/20': 9205,
'4/13/20': 10453,
'4/14/20': 11487,
'4/15/20': 12322,
'4/16/20': 13430,
'4/17/20': 14352,
'4/18/20': 15722,
'4/19/20': 17615,
'4/20/20': 18539,
'4/21/20': 20080,
'4/22/20': 21370,
'4/23/20': 23077,
'4/24/20': 24530,
'4/25/20': 26283,
'4/26/20': 27890,
'4/27/20': 29451,
'4/28/20': 31324,
'4/29/20': 33062,
'4/30/20': 34863,
'5/1/20': 37257,
'5/2/20': 39699,
'5/3/20': 42505,
'5/4/20': 46437,
'5/5/20': 49400,
'5/6/20': 52987,
'5/7/20': 56351,
'5/8/20': 59695,
'5/9/20': 62808,
'5/10/20': 67161,
'5/11/20': 70768,
'5/12/20': 74292,
'5/13/20': 78055,
'5/14/20': 81997,
'5/15/20': 85784,
'5/16/20': 90648,
'5/17/20': 95698,
'5/18/20': 100328,
'5/19/20': 106475,
'5/20/20': 112028,
'5/21/20': 118226,
'5/22/20': 124794,
'5/23/20': 131423,
'5/24/20': 138536,
'5/25/20': 144950,
'5/26/20': 150793,
'5/27/20': 158086,
'5/28/20': 165386,
'5/29/20': 173491,
'5/30/20': 181827,
'5/31/20': 190609,
},
},
]
JavaScript COVID-19 Tracker Chart - Editor Also known as Bar Graph, Column Chart or Column Graph
Showcase of LightningChart JS Bar Charts in a Racing Bar Chart context, to visualize tracking of the Co-Vid 19 virus. Tha data (country, history of cases) that is taken from API In setInterval loop data is sorted by total COVID cases per each day and top 20 cases added to the bars series in format { category: string, value: number } .
Sorting and animations are built-in to the chart feature, which makes the application code minimal and simple to maintain.