<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>ZingSoft Demo</title>
<script nonce="undefined" src="https://cdn.zingchart.com/zingchart.min.js"></script>
<style>
.grid {
display: grid;
grid-template-columns: 1fr 150px;
grid-column-gap: 1.5rem;
align-items: center;
}
.chart {
min-height: 852px;
}
.countries {
width: 150px;
max-height: 852px;
overflow: auto;
font-size: 12px;
border: 1px solid #ddd;
}
label {
margin: 0;
padding: 4px 6px;
display: flex;
cursor: pointer;
font-weight: 500;
font-size: 12px;
line-height: 1.4;
}
input[type=checkbox] {
margin: 0 4px 0 0;
width: 17px;
height: 17px;
}
.zc-body {
background-color: #fff;
}
.zc-ref {
display: none;
}
</style>
</head>
<body class="zc-body">
<div class="grid">
<div id="myChart" class="chart">
<a href="https://www.zingchart.com/" rel="noopener" class="zc-ref">Powered by ZingChart</a>
</div>
<div id="countriesChart" class="countries"></div>
</div>
<script>
ZC.LICENSE = ["569d52cefae586f634c54f86dc99e6a9", "b55b025e438fa8a98e32482b5f768ff5"]; // DEFINE CHART LOCATIONS (IDS)
// -----------------------------
// Main chart render location
let chartId = 'myChart';
// DATA
// -----------------------------
let inputEl, labelEl, nrVal;
let aData = [];
let aDataTxt = [];
let iLineX = 70;
let iLineY = 80;
let label = document.createElement('label');
let input = document.createElement('input');
// DOM ELEMENTS
// -----------------------------
let chkList = document.querySelector('#countriesChart');
let sidebarEls;
// CHART DATA
// -----------------------------
let aCountries = ['Argentina', 'Australia', 'Austria', 'Belgium', 'Bolivia', 'Brazil', 'Canada', 'Chile', 'China', 'Croatia', 'Denmark', 'Egypt', 'Finland', 'France', 'Germany', 'Greece', 'Iceland', 'India', 'Indonesia', 'Italy', 'Japan', 'Luxembourg', 'Mexico', 'Netherlands', 'Norway', 'Peru', 'Portugal', 'Romania', 'Spain', 'Switzerland', 'Thailand', 'United Kingdom', 'United States', 'Venezuela'];
// Build sidebar elements
aCountries.forEach(function(country) {
let id = country.replace(/[^a-zA-Z]/gi, '').toLowerCase();
// Create label
labelEl = label.cloneNode();
labelEl.id = 'lbl' + id;
// Create Input
inputEl = input.cloneNode();
inputEl.setAttribute('id', id);
inputEl.setAttribute('type', 'checkbox');
inputEl.setAttribute('data-jsref', 'country-input');
inputEl.checked = false;
labelEl.appendChild(inputEl);
// Add label text
labelEl.insertAdjacentHTML('beforeend', country);
// Add label to DOM
chkList.appendChild(labelEl);
});
// Store # of countries
nrVal = aCountries.length;
// Store new sidebar els
sidebarEls = Array.prototype.slice.call(document.querySelectorAll('[data-jsref="country-input"]'));
for (let i = 0; i < nrVal; i++) {
let r1 = rand(iLineX - 30, iLineX + 30);
let r2 = rand(iLineY - 20, iLineY + 20);
aData.push([r1, r2]);
aDataTxt.push(aCountries[i].replace(/[^a-zA-Z]/gi, '').toLowerCase());
}
// CHART CONFIG
// -----------------------------
let chartConfig = {
type: 'scatter',
backgroundColor: '#FFF',
title: {
text: 'Life Expectancy and Self-reported Health (OECD)',
align: 'left',
fontSize: '22px',
paddingLeft: '10px'
},
subtitle: {
text: 'Self-reported Health (scale from 0-100)',
align: 'left',
fontSize: '12x',
fontStyle: 'italic',
fontWeight: 'normal',
padding: '5px 0px 10px 10px'
},
plot: {
dataCountries: aCountries,
dataTxt: aDataTxt,
animation: {
effect: 'ANIMATION_FADE_IN',
method: 'ANIMATION_LINEAR',
sequence: 'ANIMATION_NO_SEQUENCE',
speed: 400
}
},
scaleX: {
offset: '40px',
step: 10,
lineWidth: 0,
guide: {
visible: false
},
item: {
color: '#000',
fontSize: '11px',
fontWeight: 'normal'
},
label: {
text: 'Self-reported Health (scale from 0-100)',
fontColor: '#000',
fontSize: '11px',
fontWeight: 'normal',
paddingTop: '15px'
},
markers: [{
type: 'line',
text: 'low<br><br>high',
lineStyle: 'dotted',
lineColor: '#000',
valueRange: true,
label: {
fontWeight: 'bold',
offsetX: '-42px',
paddingBottom: '40px'
},
range: [iLineX]
}],
tick: {
visible: true
}
},
scaleY: {
offset: '40px',
lineWidth: 0,
minValue: 'auto',
guide: {
visible: false
},
item: {
color: '#000',
fontSize: '11px',
fontWeight: 'normal'
},
label: {
text: 'Life Expectancy',
fontColor: '#000',
fontSize: '11px',
fontWeight: 'normal',
paddingRight: '1px'
},
markers: [{
type: 'line',
text: 'high<br><br>low',
lineColor: '#000',
lineStyle: 'dotted',
label: {
fontWeight: 'bold',
offsetY: '23px',
paddingLeft: '20px'
},
range: [iLineY]
}],
tick: {
visible: true
}
},
tooltip: {
text: '<span style="font-size:17px;font-weight:bold;">%data-countries</span><br><br>Life expectancy: <b>%node-value</b> years<br>Self-reported health: <b>%scale-key-value</b>',
align: 'left',
fontSize: '12px',
padding: '10px'
},
series: [{
values: aData,
hoverMarker: {
visible: false
},
valueBox: {
text: '%data-countries',
color: '#000',
fontSize: '11px',
fontWeight: 'bold',
jsRule: 'plotRule(2)',
offsetY: '45px'
},
tooltip: {
jsRule: 'plotRule(1)'
},
marker: {
borderColor: '#FFF',
borderWidth: '1px',
fillAngle: 45,
fillType: 'linear',
jsRule: 'plotRule(0)',
shadowDistance: '3px',
size: '20px'
}
}]
};
// RENDER CHARTS
// -----------------------------
zingchart.render({
id: chartId,
width: '100%',
height: '100%',
output: 'svg',
data: chartConfig,
events: {
load: loaded
}
});
// EVENTS
// -----------------------------
sidebarEls.forEach(function(el) {
el.addEventListener('click', handleSidebarClick);
});
// HELPER FNS
// -----------------------------
function handleSidebarClick(e) {
zingchart.exec(chartId, 'update', {
graphid: 0
});
}
// Chart loaded event
function loaded() {
setInterval(function() {
update();
}, 2500);
}
// Set rule
function plotRule(p, t) {
let obj = {},
color = '',
fontColor = '#FFF';
// Get # of checked checkboxes
let iChecked = sidebarEls.filter(function(el) {
return el.checked
}).length;
// Get target sidebar label
let label = document.querySelector('#lbl' + p["data-txt"]);
let input = document.querySelector('#' + p["data-txt"]);
if (t === '0' || t === '1') {
if (p.value <= iLineY && p.key <= iLineX) {
color = '#D01C8B #821257';
} else if (p.value > iLineY && p.key <= iLineX) {
color = '#B8E186 #799358';
fontColor = '#000';
} else if (p.value <= iLineY && p.key > iLineX) {
color = '#F1B6DA #A37C94';
fontColor = '#000';
} else if (p.value > iLineY && p.key > iLineX) {
color = '#4DAC26 #2B5E15';
}
// Set background color
label.style.backgroundColor = color.split(' ')[0];
obj['background-color'] = color;
obj['font-color'] = fontColor;
if (t === '0') {
obj['shadow'] = input.checked;
obj['border-color'] = input.checked ? '#666' : '#fff';
obj['size'] = input.checked ? 22 : 20;
obj['alpha'] = input.checked ? 1 : (iChecked === 0 ? 0.75 : 0.05);
}
} else {
obj['visible'] = input.checked;
}
return obj;
};
// Random
function rand(min, max) {
return Math.round(min + (max - min) * Math.random());
}
// Update chart
function update() {
for (let i = 0; i < nrVal; i++) {
aData[i][0] += rand(-2, 2);
aData[i][1] += rand(-2, 2);
}
zingchart.exec(chartId, 'setseriesvalues', {
plotindex: 0,
values: aData
});
};
</script>
</body>
</html>
// DEFINE CHART LOCATIONS (IDS)
// -----------------------------
// Main chart render location
let chartId = 'myChart';
// DATA
// -----------------------------
let inputEl, labelEl, nrVal;
let aData = [];
let aDataTxt = [];
let iLineX = 70;
let iLineY = 80;
let label = document.createElement('label');
let input = document.createElement('input');
// DOM ELEMENTS
// -----------------------------
let chkList = document.querySelector('#countriesChart');
let sidebarEls;
// CHART DATA
// -----------------------------
let aCountries = ['Argentina', 'Australia', 'Austria', 'Belgium', 'Bolivia', 'Brazil', 'Canada', 'Chile', 'China', 'Croatia', 'Denmark', 'Egypt', 'Finland', 'France', 'Germany', 'Greece', 'Iceland', 'India', 'Indonesia', 'Italy', 'Japan', 'Luxembourg', 'Mexico', 'Netherlands', 'Norway', 'Peru', 'Portugal', 'Romania', 'Spain', 'Switzerland', 'Thailand', 'United Kingdom', 'United States', 'Venezuela'];
// Build sidebar elements
aCountries.forEach(function (country) {
let id = country.replace(/[^a-zA-Z]/gi, '').toLowerCase();
// Create label
labelEl = label.cloneNode();
labelEl.id = 'lbl' + id;
// Create Input
inputEl = input.cloneNode();
inputEl.setAttribute('id', id);
inputEl.setAttribute('type', 'checkbox');
inputEl.setAttribute('data-jsref', 'country-input');
inputEl.checked = false;
labelEl.appendChild(inputEl);
// Add label text
labelEl.insertAdjacentHTML('beforeend', country);
// Add label to DOM
chkList.appendChild(labelEl);
});
// Store # of countries
nrVal = aCountries.length;
// Store new sidebar els
sidebarEls = Array.prototype.slice.call(document.querySelectorAll('[data-jsref="country-input"]'));
for (let i = 0; i < nrVal; i++) {
let r1 = rand(iLineX - 30, iLineX + 30);
let r2 = rand(iLineY - 20, iLineY + 20);
aData.push([r1, r2]);
aDataTxt.push(aCountries[i].replace(/[^a-zA-Z]/gi, '').toLowerCase());
}
// CHART CONFIG
// -----------------------------
let chartConfig = {
type: 'scatter',
backgroundColor: '#FFF',
title: {
text: 'Life Expectancy and Self-reported Health (OECD)',
align: 'left',
fontSize: '22px',
paddingLeft: '10px'
},
subtitle: {
text: 'Self-reported Health (scale from 0-100)',
align: 'left',
fontSize: '12x',
fontStyle: 'italic',
fontWeight: 'normal',
padding: '5px 0px 10px 10px'
},
plot: {
dataCountries: aCountries,
dataTxt: aDataTxt,
animation: {
effect: 'ANIMATION_FADE_IN',
method: 'ANIMATION_LINEAR',
sequence: 'ANIMATION_NO_SEQUENCE',
speed: 400
}
},
scaleX: {
offset: '40px',
step: 10,
lineWidth: 0,
guide: {
visible: false
},
item: {
color: '#000',
fontSize: '11px',
fontWeight: 'normal'
},
label: {
text: 'Self-reported Health (scale from 0-100)',
fontColor: '#000',
fontSize: '11px',
fontWeight: 'normal',
paddingTop: '15px'
},
markers: [{
type: 'line',
text: 'low<br><br>high',
lineStyle: 'dotted',
lineColor: '#000',
valueRange: true,
label: {
fontWeight: 'bold',
offsetX: '-42px',
paddingBottom: '40px'
},
range: [iLineX]
}],
tick: {
visible: true
}
},
scaleY: {
offset: '40px',
lineWidth: 0,
minValue: 'auto',
guide: {
visible: false
},
item: {
color: '#000',
fontSize: '11px',
fontWeight: 'normal'
},
label: {
text: 'Life Expectancy',
fontColor: '#000',
fontSize: '11px',
fontWeight: 'normal',
paddingRight: '1px'
},
markers: [{
type: 'line',
text: 'high<br><br>low',
lineColor: '#000',
lineStyle: 'dotted',
label: {
fontWeight: 'bold',
offsetY: '23px',
paddingLeft: '20px'
},
range: [iLineY]
}],
tick: {
visible: true
}
},
tooltip: {
text: '<span style="font-size:17px;font-weight:bold;">%data-countries</span><br><br>Life expectancy: <b>%node-value</b> years<br>Self-reported health: <b>%scale-key-value</b>',
align: 'left',
fontSize: '12px',
padding: '10px'
},
series: [{
values: aData,
hoverMarker: {
visible: false
},
valueBox: {
text: '%data-countries',
color: '#000',
fontSize: '11px',
fontWeight: 'bold',
jsRule: 'plotRule(2)',
offsetY: '45px'
},
tooltip: {
jsRule: 'plotRule(1)'
},
marker: {
borderColor: '#FFF',
borderWidth: '1px',
fillAngle: 45,
fillType: 'linear',
jsRule: 'plotRule(0)',
shadowDistance: '3px',
size: '20px'
}
}]
};
// RENDER CHARTS
// -----------------------------
zingchart.render({
id: chartId,
width: '100%',
height: '100%',
output: 'svg',
data: chartConfig,
events: {
load: loaded
}
});
// EVENTS
// -----------------------------
sidebarEls.forEach(function (el) {
el.addEventListener('click', handleSidebarClick);
});
// HELPER FNS
// -----------------------------
function handleSidebarClick(e) {
zingchart.exec(chartId, 'update', {
graphid: 0
});
}
// Chart loaded event
function loaded() {
setInterval(function () {
update();
}, 2500);
}
// Set rule
function plotRule(p, t) {
let obj = {}, color = '', fontColor = '#FFF';
// Get # of checked checkboxes
let iChecked = sidebarEls.filter(function (el) { return el.checked }).length;
// Get target sidebar label
let label = document.querySelector('#lbl' + p["data-txt"]);
let input = document.querySelector('#' + p["data-txt"]);
if (t === '0' || t === '1') {
if (p.value <= iLineY && p.key <= iLineX) {
color = '#D01C8B #821257';
} else if (p.value > iLineY && p.key <= iLineX) {
color = '#B8E186 #799358';
fontColor = '#000';
} else if (p.value <= iLineY && p.key > iLineX) {
color = '#F1B6DA #A37C94';
fontColor = '#000';
} else if (p.value > iLineY && p.key > iLineX) {
color = '#4DAC26 #2B5E15';
}
// Set background color
label.style.backgroundColor = color.split(' ')[0];
obj['background-color'] = color;
obj['font-color'] = fontColor;
if (t === '0') {
obj['shadow'] = input.checked;
obj['border-color'] = input.checked ? '#666' : '#fff';
obj['size'] = input.checked ? 22 : 20;
obj['alpha'] = input.checked ? 1 : (iChecked === 0 ? 0.75 : 0.05);
}
}
else {
obj['visible'] = input.checked;
}
return obj;
};
// Random
function rand(min, max) {
return Math.round(min + (max - min) * Math.random());
}
// Update chart
function update() {
for (let i = 0; i < nrVal; i++) {
aData[i][0] += rand(-2, 2);
aData[i][1] += rand(-2, 2);
}
zingchart.exec(chartId, 'setseriesvalues', {
plotindex: 0,
values: aData
});
};