chart2 = {
const chartWidth = 650;
const chartHeight = 550;
const margin = { top: 120, right: 150, bottom: 120, left: 100 };
const targets = ['heartDisease', 'kidneyDisease', 'skinCancer'];
const factors = ['heartDisease', 'kidneyDisease', 'skinCancer'];
const correlationMatrix = [];
targets.forEach(target => {
factors.forEach(factor => {
const correlation = pointBiserialCorrelation(data, target, factor);
correlationMatrix.push({target, factor, correlation});
});
});
const xScale = d3.scaleBand()
.domain(factors)
.range([margin.left, chartWidth - margin.right])
.padding(0.05);
const yScale = d3.scaleBand()
.domain(targets)
.range([margin.top, chartHeight - margin.bottom])
.padding(0.1);
const colorScale = d3.scaleSequential(d3.interpolateRdBu)
.domain([1, -1]);
const labelMap = {heartDisease: 'Heart Disease',
kidneyDisease: 'Kidney Disease',
skinCancer: 'Skin Cancer'
};
// Transform the label
const formatLabel = (label) => labelMap[label] || label;
// Create the SVG element for the heatmap
const svg = d3.create('svg')
.attr('viewBox', `0 0 ${chartWidth} ${chartHeight}`)
.attr('preserveAspectRatio', 'xMidYMid meet')
.style('width', '100%')
.style('height', 'auto');
// Define the font style for the chart
const fontFamily = 'Arial, sans-serif';
const fontSize = '12px';
// Create cells for the heatmap
svg.selectAll('rect')
.data(correlationMatrix)
.enter()
.append('rect')
.attr('x', d => xScale(d.factor)) // Factors on x-axis
.attr('y', d => yScale(d.target)) // Targets on y-axis
.attr('width', xScale.bandwidth())
.attr('height', yScale.bandwidth())
.attr('fill', d => colorScale(d.correlation)); // Set color based on correlation value
// Add labels for the correlation values inside the cells
svg.selectAll('text')
.data(correlationMatrix)
.enter()
.append('text')
.attr('x', d => xScale(d.factor) + xScale.bandwidth() / 2)
.attr('y', d => yScale(d.target) + yScale.bandwidth() / 2)
.attr('dy', '.35em')
.attr('text-anchor', 'middle')
.style('font-family', fontFamily) // Apply font family
.style('font-size', '16px') // Increase font size for matrix labels
.text(d => d3.format('.2f')(d.correlation)) // Round to 2 decimal places
.attr('fill', 'black');
// Disease names on the y-axis
svg.append('g')
.attr('transform', `translate(0, ${margin.top})`)
.call(d3.axisTop(xScale)) // Place factors on the top axis
.selectAll('text')
.style('font-family', fontFamily) // Apply font family
.style('font-size', '12px') // Increase font size for axis labels
.text(d => formatLabel(d));
// Factors on the x-axis
svg.append('g')
.attr('transform', `translate(${margin.left}, 0)`)
.call(d3.axisLeft(yScale)) // Place targets on the left axis
.selectAll('text')
.style('font-family', fontFamily) // Apply font family
.style('font-size', '12px') // Increase font size for axis labels
.text(d => formatLabel(d));
// Add a color legend centered below the chart
const legendHeight = 20;
const legendWidth = 300;
const legend = svg.append('g')
.attr('transform', `translate(${(chartWidth - legendWidth) / 2}, ${chartHeight - margin.bottom + 30})`);
const legendScale = d3.scaleLinear()
.domain([1, -1])
.range([0, legendWidth]);
// Create a gradient for the color scale (blue on left, red on right)
const gradient = legend.append('defs')
.append('linearGradient')
.attr('id', 'gradient')
.attr('x1', '0%')
.attr('x2', '100%')
.attr('y1', '0%')
.attr('y2', '0%');
// Blue on the left (negative correlation)
gradient.append('stop')
.attr('offset', '0%')
.attr('stop-color', "#61b8e7"); // The blue you requested
// Red on the right (positive correlation)
gradient.append('stop')
.attr('offset', '100%')
.attr('stop-color', "#d23626"); // The red you requested
legend.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', legendWidth)
.attr('height', legendHeight)
.style('fill', 'url(#gradient)');
// Add numerical labels for the horizontal legend
legend.append('text')
.attr('x', 0)
.attr('y', legendHeight + 15)
.attr('dy', '.35em')
.attr('text-anchor', 'middle')
.style('font-family', fontFamily) // Apply font family
.style('font-size', '12px') // Increase font size for legend labels
.text('Neg. Correlation (-1.0)') // Negative correlation label
.attr('fill', 'black');
legend.append('text')
.attr('x', legendWidth)
.attr('y', legendHeight + 15)
.attr('dy', '.35em')
.attr('text-anchor', 'middle')
.style('font-family', fontFamily) // Apply font family
.style('font-size', '12px') // Increase font size for legend labels
.text('Pos. Correlation (1.0)') // Positive correlation label
.attr('fill', 'black');
// Add title at the top
svg.append('text')
.attr('x', chartWidth / 2) // Center the title horizontally
.attr('y', margin.top / 2) // Position the title at the top
.attr('text-anchor', 'middle') // Center text
.attr('font-family', 'Arial, sans-serif') // Apply font
.attr('font-size', '20px') // Font size for the title
.attr('font-weight', 'bold') // Make the font bold
.text('Disease Co-Occurrence Correlation');
return svg.node();
}