echarts = require("echarts@5")
// dados
dic_genero_idade = FileAttachment("../fontes/diabetes_genero_idade.json").json();
dados_genero = dic_genero_idade.filter(d => d.idade >= 0 && d.idade <= 100);
chart_dic_genero_idade = {
// elemento inicia invisível (sem piscada)
const el = DOM.element('div', {
className: 'chart-holder chart-pending',
style: 'width:100%; height:420px; min-height:420px;'
});
function buildOnce() {
if (el._built) return;
el._built = true;
const chart = echarts.init(el);
const idades = dados_genero.map(d => d.idade);
const generos = Object.keys(dados_genero[0]).filter(k => k !== 'idade');
const generosParaMarcar = ['Fem', 'Masc'];
// paleta opcional por série (use as suas cores se preferir)
const coresPorGenero = { Masc: '#FF8C00', Fem: '#008080' };
const option = {
title: { text: 'Mortes por Gênero e Idade (0 a 100 anos)', left: 'center', top: 10 },
tooltip: { trigger: 'axis' },
legend: { data: generos, bottom: 10 },
grid: { top: 80, left: '3%', right: '4%', bottom: '15%', containLabel: true },
xAxis: { type: 'category', boundaryGap: false, data: idades, name: 'Idade' },
yAxis: { type: 'value', name: 'Quantidade' },
animationDuration: 2000,
animationEasing: 'cubicOut',
series: generos.map(g => ({
name: g,
type: 'line',
data: dados_genero.map(d => d[g] ?? 0),
itemStyle: { color: coresPorGenero[g] },
lineStyle: { color: coresPorGenero[g] }
}))
};
chart.setOption(option);
// adiciona markPoints após a animação das linhas
setTimeout(() => {
const seriesMP = generos.map((g) => {
const dados = dados_genero.map(d => d[g] ?? 0);
let markPoint = {};
if (generosParaMarcar.includes(g)) {
const maxv = Math.max(...dados);
const i = dados.indexOf(maxv);
const idadePico = idades[i];
const cor = coresPorGenero[g] || '#666';
markPoint = {
// >>> animação do markPoint restaurada <<<
animation: true,
animationDuration: 800,
animationEasing: 'cubicOut',
data: [{
// você pode trocar por type: 'max' se preferir
coord: [i, maxv],
symbol: 'circle', // 'pin' para balão em gota
symbolSize: 12, // <<< diminua/aumente o "balão"
itemStyle: {
color: cor,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: true,
position: 'top',
offset: [0, -6],
// >>> caixa no rótulo <<<
backgroundColor: 'rgba(255,255,255,0.95)',
borderColor: cor,
borderWidth: 1,
borderRadius: 6,
padding: [6, 8],
color: '#333',
fontSize: 12,
fontWeight: 'bold',
lineHeight: 16,
formatter: `Pico ${g}: ${idadePico} anos`
}
}]
};
}
return { name: g, type: 'line', data: dados, markPoint };
});
chart.setOption({ series: seriesMP });
}, 2100);
// garante tamanho correto e revela
chart.resize();
new ResizeObserver(() => chart.resize()).observe(el);
window.addEventListener('resize', () => chart.resize());
el.classList.remove('chart-pending');
el.classList.add('chart-ready');
invalidation.then(() => chart.dispose());
}
// inicializa já, se visível; senão, espera a aba abrir
requestAnimationFrame(() => {
const pane = el.closest('.tab-pane');
if (!pane || pane.classList.contains('active') || pane.style.display !== 'none') {
requestAnimationFrame(buildOnce);
} else {
const onShow = ev => {
const target = ev.target && ev.target.getAttribute('data-bs-target');
if (target === '#' + pane.id) {
requestAnimationFrame(buildOnce);
document.removeEventListener('shown.bs.tab', onShow);
}
};
document.addEventListener('shown.bs.tab', onShow);
}
});
return el;
}Diabetes
Destaques: Gênero
O padrão de proporção enmtre homens e mulheres é bem semelhante à maioria dos grupos de doenças. Para causas mal definidas, percebe-se um número de mortalidade gramde entre 0 e 2 anos que somam 636 mortes. Homens representam 44.5% do total de mortes.
dic_raca_cor_idade = FileAttachment("../fontes/diabetes_raca_cor_idade.json").json();
dados_filtrados = dic_raca_cor_idade.filter(d => d.idade >= 0 && d.idade <= 100);
chart_raca_cor_idade = {
// 1) cria o elemento já escondido (sem piscada)
const el = DOM.element('div', {
className: 'chart-holder chart-pending',
style: 'width:100%; height:420px; min-height:420px;'
});
// paleta (ajuste se quiser)
const palette = {
Branca: '#2E86AB',
Parda: '#A23B72',
Preta: '#F18F01',
Amarela: '#C73E1D',
Indígena: '#592E83'
};
// 2) função que constrói apenas uma vez
function buildOnce() {
if (el._built) return;
el._built = true;
const chart = echarts.init(el);
const idades = dados_filtrados.map(d => d.idade);
const racas = Object.keys(dados_filtrados[0]).filter(k => k !== 'idade');
const racasParaMarcar = ['Branca', 'Preta', 'Parda'];
const option = {
title: { text: 'Mortes por Raça/Cor e Idade (0 a 100 anos)', left: 'center', top: 10 },
tooltip: { trigger: 'axis' },
legend: { data: racas, bottom: 10 },
grid: { top: 80, left: '3%', right: '4%', bottom: '15%', containLabel: true },
xAxis: { type: 'category', boundaryGap: false, data: idades, name: 'Idade' },
yAxis: { type: 'value', name: 'Quantidade' },
// >>> animação das linhas (mesmo padrão)
animationDuration: 2000,
animationEasing: 'cubicOut',
series: racas.map((r, i) => ({
name: r,
type: 'line',
data: dados_filtrados.map(d => d[r] ?? 0),
itemStyle: { color: palette[r] || `hsl(${i * 72},70%,50%)` },
lineStyle: { color: palette[r] || `hsl(${i * 72},70%,50%)` }
}))
};
chart.setOption(option);
// 3) markPoints com a MESMA animação do gráfico anterior
setTimeout(() => {
const seriesWithMP = racas.map((r, i) => {
const dados = dados_filtrados.map(d => d[r] ?? 0);
let markPoint = {};
if (racasParaMarcar.includes(r)) {
const maxv = Math.max(...dados);
const idx = dados.indexOf(maxv);
const idadePico = idades[idx];
const cor = palette[r] || `hsl(${i * 72},70%,50%)`;
markPoint = {
animation: true,
animationDuration: 800,
animationEasing: 'cubicOut',
data: [{
coord: [idx, maxv], // ponto do pico
symbol: 'circle', // use 'pin' se quiser balão em gota
symbolSize: 12, // tamanho do marcador
itemStyle: {
color: cor,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: true,
position: 'top',
offset: [0, -6],
// >>> caixa no rótulo
backgroundColor: 'rgba(255,255,255,0.95)',
borderColor: cor,
borderWidth: 1,
borderRadius: 6,
padding: [6, 8],
color: '#333',
fontSize: 12,
fontWeight: 'bold',
lineHeight: 16,
formatter: `Pico ${r}: ${idadePico} anos`
}
}]
};
}
return { name: r, type: 'line', data: dados, markPoint };
});
chart.setOption({ series: seriesWithMP });
}, 2100);
// 4) garante tamanho correto e revela sem piscada
chart.resize();
new ResizeObserver(() => chart.resize()).observe(el);
window.addEventListener('resize', () => chart.resize());
el.classList.remove('chart-pending');
el.classList.add('chart-ready');
// limpeza
invalidation.then(() => chart.dispose());
}
// 5) constrói já se visível; senão, espera a aba abrir
const pane = el.closest('.tab-pane');
if (!pane || pane.classList.contains('active') || pane.style.display !== 'none') {
requestAnimationFrame(buildOnce);
} else {
const onShow = ev => {
const target = ev.target && ev.target.getAttribute('data-bs-target');
if (target === '#' + pane.id) {
requestAnimationFrame(buildOnce);
document.removeEventListener('shown.bs.tab', onShow);
}
};
document.addEventListener('shown.bs.tab', onShow);
}
return el; // ojs renderiza este elemento
}Destaques: Raça/Cor
Fator que chama a atenção é que, na fase adulta pessoas pardas e brancas têm maior probabilidade de morrer na mesma idade (aos 75 anos).
Pessoas pretas mantém maior probabilidade de morte aos 72 anos, 3 antes que pessoas brancas.
dic_raca_cor_ano = FileAttachment("../fontes/diabetes_raca_cor_ano.json").json();
dados_ano = dic_raca_cor_ano
.map(d => ({ ...d, ano: +d.ano }))
.filter(d => !Number.isNaN(d.ano))
.sort((a, b) => d3.ascending(a.ano, b.ano));
chart_raca_cor_ano = {
// elemento inicia invisível (sem piscada)
const el = DOM.element('div', {
className: 'chart-holder chart-pending',
style: 'width:100%; height:420px; min-height:420px;'
});
function buildOnce() {
if (el._built) return;
el._built = true;
const chart = echarts.init(el);
const anos = dados_ano.map(d => d.ano);
const racas = Object.keys(dados_ano[0] || {}).filter(k => k !== 'ano');
const racasParaMarcar = ['Branca', 'Preta', 'Parda'];
const palette = {
Branca: '#2E86AB',
Parda: '#A23B72',
Preta: '#F18F01',
Amarela: '#C73E1D',
Indígena: '#592E83'
};
const option = {
title: { text: 'Mortes por Raça/Cor ao longo dos anos', left: 'center', top: 10 },
tooltip: { trigger: 'axis' },
legend: { data: racas, bottom: 10 },
grid: { top: 80, left: '3%', right: '4%', bottom: '15%', containLabel: true },
xAxis: { type: 'category', boundaryGap: false, data: anos, name: 'Ano' },
yAxis: { type: 'value', name: 'Quantidade' },
animationDuration: 2000,
animationEasing: 'cubicOut',
series: racas.map((r, i) => {
const dados = dados_ano.map(d => +d[r] || 0);
const cor = palette[r] || `hsl(${i * 72},70%,50%)`;
return { name: r, type: 'line', data: dados, itemStyle: { color: cor }, lineStyle: { color: cor } };
})
};
chart.setOption(option);
// adiciona markPoints após a animação
setTimeout(() => {
const seriesMP = racas.map((r, i) => {
const dados = dados_ano.map(d => +d[r] || 0);
const cor = palette[r] || `hsl(${i * 72},70%,50%)`;
let markPoint = {};
if (racasParaMarcar.includes(r) && dados.length) {
const maxv = Math.max(...dados);
const idx = dados.indexOf(maxv);
const anoPico = anos[idx];
markPoint = {
data: [{
type: 'max', name: 'Pico',
label: { show: false, position: 'top', formatter: `${r} - pico: ${anoPico}` },
symbol: 'circle', symbolSize: 4, itemStyle: { color: cor }
}]
};
}
return { name: r, type: 'line', data: dados, itemStyle: { color: cor }, lineStyle: { color: cor }, markPoint };
});
chart.setOption({ series: seriesMP });
}, 2100);
// garante tamanho correto e revela
chart.resize();
new ResizeObserver(() => chart.resize()).observe(el);
window.addEventListener('resize', () => chart.resize());
el.classList.remove('chart-pending');
el.classList.add('chart-ready');
invalidation.then(() => chart.dispose());
}
// inicializa já, se visível; senão, espera a aba abrir
requestAnimationFrame(() => {
const pane = el.closest('.tab-pane');
if (!pane || pane.classList.contains('active') || pane.style.display !== 'none') {
requestAnimationFrame(buildOnce);
} else {
const onShow = ev => {
const target = ev.target && ev.target.getAttribute('data-bs-target');
if (target === '#' + pane.id) {
requestAnimationFrame(buildOnce);
document.removeEventListener('shown.bs.tab', onShow);
}
};
document.addEventListener('shown.bs.tab', onShow);
}
});
return el;
}Lista de causas por diabetes
| Código | Descrição |
|---|---|
| E10 | Diabetes mellitus insulinodependente |
| E11 | Diabetes mellitus não-insulinodependente |
| E12 | Diabetes mellitus associado à desnutrição |
| E13 | Outros tipos especificados de diabetes |
| E14 | Diabetes mellitus não especificado |