Disclaimer1111: We provide best estimates for data that has not been disclosed or is deemed to have been under-reported. For more details, visit our FAQs.
' +
'
' +
'
'
layout[0].appendChild(d)
}
function showLoadingOverlay() {
$('#error-box').addClass('d-none');
document.getElementById('loading-overlay').classList.remove('loading-hidden');
}
function hideLoadingOverlay() {
document.getElementById('loading-overlay').classList.add('loading-hidden');
}
function getSelectedOptions() {
let filter = $('input[type=radio][name=selector]:checked').val();
let topBy = $('input[type=radio][name=topBy]:checked').val();
let scaleBy = $('input[type=radio][name=scaleBy]:checked').val();
let show = $('input[type=radio][name=show]:checked').val();
let country = $('#country').val();
let company = $('#company').val();
let index = $('#index').val();
let sector = $('#sector').val();
let count = $('#count').val();
let viewType ="v2";
return {filter, topBy, show, country, company, index, sector, count, scaleBy, viewType};
}
async function callApi(data) {
showLoadingOverlay()
const endpoint = "https://blue-ngo.ew.r.appspot.com/data/graph";
try {
const response = await fetch(endpoint, { method: "POST", headers: {"Content-Type": "application/json"},
body: JSON.stringify(data)
});
if (response.ok) {
const responseData = await response.json();
if (responseData.code == 200) {
unitCreateBubbleChart(data, responseData.data)
//unitCreateBubbleChart(data, responseData.data)
} else {
$('#error-box').removeClass('d-none');
}
hideLoadingOverlay()
} else {
$('#error-box').removeClass('d-none');
console.error(`API call failed with status: ${response.status}`);
}
} catch (error) {
$('#error-box').removeClass('d-none');
console.error("Error during API call:", error);
}
}
async function downLoad(data) {
const endpoint = "https://blue-ngo.ew.r.appspot.com/data/download";
try {
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
if (response.ok) {
const responseData = await response.blob();
const url = window.URL.createObjectURL(responseData);
const downloadLink = document.createElement('a');
downloadLink.href = url;
downloadLink.download = 'carbonary-data.' +data.format.toLowerCase();
downloadLink.style.display = 'none';
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
} else {
console.error(`API call failed with status: ${response.status}`);
}
} catch (error) {
console.error("Error during API call:", error);
}
}
function logScaleAndNormalize(dataArray, newSizeMin, newSizeMax) {
if (dataArray.length === 1) { return [100];}
const logDataArray = dataArray.map(value => Math.log10(value.marketCapitalization));
let minValue = Math.min(...logDataArray);
if (minValue === -Infinity) { minValue = -1000;}
let maxValue = Math.max(...logDataArray);
if (maxValue === minValue) { return logDataArray.map(() => newSizeMin);}
const normalizedDataArray = logDataArray.map(value => {
const normalizedValue = ((value - minValue) / (maxValue - minValue)) * (newSizeMax - newSizeMin) + newSizeMin;
return normalizedValue;
});
return normalizedDataArray;
}
function truncateString(inputString) {
if (inputString.length <= 10) { return inputString;} else {return inputString.substring(0, 10) + "..";}
}
function formatCurrencyUSD(value) {
const isNegative = value < 0;
if (isNegative) {
value = -value;
}
value = Math.round(value);
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
maximumFractionDigits: 0,
});
const formattedValue = formatter.format(value);
return isNegative ? `- ${formattedValue}` : formattedValue;
}
function createHover(entry) {
const hoverTemplate = `Name: ${entry.name} Country: ${entry.country} Ticker: ${entry.ticker} Financial capacity: ${formatCurrencyUSD(entry.incomeBeforeTax)} per ton CO2eq % Total residual emissions offset: ${toPercentage(entry.progress)}`;
return hoverTemplate
}
function toPercentage(decimal, precision = 0) {
const percentage = decimal * 100;
const rounded = percentage.toFixed(precision);
return `${rounded}%`;
}
function textPosition() {
const directions = ["bottom"];
const randomIndex = Math.floor(Math.random() * directions.length);
return directions[randomIndex];
}
function determineHeight() {
return 150;
}
bluevizi.initTooltips=function() {
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
/*const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl,{
trigger: 'manual'
}))
tooltipList.forEach(function (tooltip) {
tooltip.show();
});*/
}
function createRowElement(code, name, color,tooltip) {
// Create new elements
let rowDiv = document.createElement('div');
let colDiv1 = document.createElement('div');
let colDiv2 = document.createElement('div');
let chartDiv = document.createElement('div');
rowDiv.className = 'row mb-3 bg-body';
colDiv1.className = 'col-md-1 d-flex justify-content-center align-items-center text-center rounded';
colDiv2.className = 'col-md-11 text-center shadow rounded';
colDiv1.style.backgroundColor = color;
colDiv1.style.padding = '5px';
colDiv1.style.borderRadius = '10%';
colDiv1.style.color = 'white';
colDiv1.style.fontSize = '30px';
colDiv1.style.fontWeight = 900;
colDiv1.textContent = `${code}`;
colDiv1.setAttribute('data-bs-placement', 'right');
colDiv1.setAttribute('data-bs-toggle', 'tooltip');
colDiv1.setAttribute('data-bs-html', 'true');
colDiv1.setAttribute('data-bs-title', tooltip);
colDiv1.setAttribute('data-bs-title', tooltip);
colDiv1.setAttribute('data-bs-custom-class', `custom-tooltip-${code}`)
chartDiv.id = `chart-container-${code}`;
colDiv2.appendChild(chartDiv);
rowDiv.appendChild(colDiv1);
rowDiv.appendChild(colDiv2);
return rowDiv;
}
function createChar(code, index) {
let chartDiv = document.createElement('div');
chartDiv.id = `chart-${code}-${index}`;
let c =document.getElementById(`chart-container-${code}`)
c.appendChild(chartDiv);
return chartDiv;
}
function determineChunkSize() {
var width = $('#staticContainer').width();
console.log(window.innerWidth);
console.log(width);
if (width <=400) {
return 3;
} else if (width <= 768) {
return 5;
} else {
return 10;
}
}
function chunkArray(array, chunkSize) {
let result = [];
for (let i = 0; i < array.length; i += chunkSize) {
result.push(array.slice(i, i + chunkSize));
}
return result;
}
function build(key,bucket, index) {
let names = bucket.map(label => label.name);
let trace = {
x: names,
y: new Array(names.length).fill(0),
text: bucket.map((entry) => `${truncateString(entry.name)}`),
textposition: bucket.map((entry) => textPosition()),
hovertemplate: bucket.map((entry) => createHover(entry)),
mode: "markers+text",
customdata: bucket.map((entry) => "https://data.carbonary.com/companies/idx/" + entry.name),
marker: {
size: bucket.map((entry)=> entry.normalizedMarketCap), //logScaleAndNormalize(bucket, 20, 80),
color: bucket.map((entry) => convertLetterToColor(entry.classification)),
opacity: 0.6,
}
};
let config = {responsive: true, displaylogo: false, displayModeBar: false}
let layout = {
hoverlabel: {
font: {
color: 'black' // Font color for the hover labels
}
},
height: determineHeight(),
autosize: true,
usePlotlyDefault: false,
plot_bgcolor: 'rgba(0,0,0,0)',
margin: { // Adjust the margins to remove extra space
l: 0,
r: 0,
b: 0,
t: 0,
pad: 0
},
xaxis: {
showticklabels: false,
showgrid: false,
zeroline: false,
},
yaxis: {
showticklabels: false,
showgrid: false,
zeroline: false,
},
font: {
family: 'adelle-sans;',
size: 10,
color: '#000'
},
hovermode: "closest",
showlegend: false,
dragmode:false
};
createChar(key,index)
const chartId = `chart-${key}-${index}`;
let plotlyChart = document.getElementById(chartId);
Plotly.newPlot(plotlyChart, [trace], layout, config);
// Add hover event
plotlyChart.on('plotly_hover', function(data){
changeCursorStyle(chartId, 'pointer');
});
// Add unhover event
plotlyChart.on('plotly_unhover', function(data){
changeCursorStyle(chartId, 'default');
});
// Add click event
plotlyChart.on('plotly_click', function(data){
let cnt = data.points.length;
for(i=0; i < cnt; i++){
let url = data.points[i].customdata
bluevizi.gtag('event', 'click', {
'event_category': 'bubble',
'event_label': data.points[i].text
});
window.open(url, '_blank');
}
});
}
function changeCursorStyle(id, style){
let plotlyChart = $('#' + id + ' .nsewdrag');
if(plotlyChart.length > 0) {
plotlyChart.css('cursor', style);
}
}
function unitCreateBubbleChart(payload, postData) {
let lb =postData.labels
let container =document.getElementById('graphcontainer')
for (let key in lb) {
if (lb.hasOwnProperty(key)) {
let traces = lb[key];
traces.sort((a, b) => a.name.localeCompare(b.name));
if (traces.length > 0){
let tracesBuckets = chunkArray(traces, determineChunkSize());
let rowElement = createRowElement(key, convertLetterToName(key),convertLetterToColor(key),getToolTip(key))
container.appendChild(rowElement)
tracesBuckets.forEach((bucket, index) => build(key,bucket,index))
}else {
let rowElement = createRowElement(key, convertLetterToName(key),convertLetterToColor(key),getToolTip(key))
container.appendChild(rowElement)
}
}
}
bluevizi.initTooltips()
}
function clearPlot() {
document.getElementById('graphcontainer').innerHTML='';
}
function getToolTip(letter) {
let tooltipContent = {
"A": "
All residual emissions offset. Excellent transparency.
",
"B": "
At least 50% of residual emissions offset, companies with high financial ability are excluded from this category as this should, arguably, enable them to offset more. Good transparency.
",
"C": "
Core* residual emissions offset. Good transparency.
",
"D": "
At least 50% of core* residual emissions offset. Companies with high financial ability are excluded from this category as this should, arguably, enable them to offset more. Good transparency.
",
"E": "
Minimal to no residual emissions offset. Poor transparency.
",
"F": "
Little to no disclosure.
",
};
/*let tooltipContent = {
"A": "
Reached net-zero
Good transparency
",
"B": "
On the way to net-zero
Good transparency
Progress in line with financial capacity
",
"C": "
Reached carbon neutrality
Satisfactory transparency
",
"D": "
On the way to carbon neutrality
Good transparency
Progress in line with financial capacity
",
"E": "
Limited progress to carbon neutrality
Minimal transparency
",
"F": "
No transparency
",
};*/
/*-let tooltipContent = {
"A": "Reached net-zero\nGood transparency",
"B": "On the way to net-zero Good transparency Progress in line with financial capacity",
"C": "Reached carbon neutrality Satisfactory transparency",
"D": "On the way to carbon neutrality Good transparency Progress in line with financial capacity",
"E": "Limited progress to carbon neutrality Minimal transparency",
"F": "No transparency",
};*/
return tooltipContent[letter.toUpperCase()] || 'Invalid input';
}
function convertLetterToColor(letter) {
const colorMap = {
'A': '#7CC644',
'B': '#1C98ED',
'C': '#FFD230',
'D': '#EE6D23',
'E': '#CB1717',
'F': '#818289',
'Z': '#090808',
};
return colorMap[letter.toUpperCase()] || 'Invalid input';
}
function convertLetterToName(letter) {
const textMap = {
'A': 'Leading',
'B': 'Striving',
'C': 'Transitioning',
'D': 'Exploring',
'E': 'Lagging',
'F': 'Non-compliant',
'Z': '#090808',
};
return textMap[letter.toUpperCase()] || 'Invalid input';
}
return bluevizi;
})(bluevizi || {});
bluevizi.init();