chart1 = {
const chartWidth = 800;
const chartHeight = 700;
const margin = { top: 120, right: 150, bottom: 120, left: 100 };
const targets = ['heartDisease', 'kidneyDisease', 'skinCancer'];
const factors = ['bmi', 'smoking', 'alcoholDrinking', 'stroke', 'physicalHealth',
'mentalHealth', 'diffWalking', 'sex', 'ageCategory', 'raceCategory',
'diabetic', 'physicalActivity', 'genHealth', 'sleepTime', 'asthma'];
const correlationMatrix = [];
targets.forEach(target => {
factors.forEach(factor => {
const correlation = pointBiserialCorrelation(data, target, factor);
correlationMatrix.push({ target, factor, correlation });
});
});
const xScale = d3.scaleBand()
.domain(targets)
.range([margin.left, chartWidth - margin.right])
.padding(0.02);
const yScale = d3.scaleBand()
.domain(factors)
.range([margin.top, chartHeight - margin.bottom])
.padding(0.15);
const colorScale = d3.scaleSequential(d3.interpolateRdBu).domain([1, -1]);
const labelMap = {
heartDisease: 'Heart Disease', bmi: 'BMI', smoking: 'Smoking',
alcoholDrinking: 'Alcohol Drinking', stroke: 'Stroke',
physicalHealth: 'Physical Health', mentalHealth: 'Mental Health',
diffWalking: 'Difficulty Walking', sex: 'Sex', ageCategory: 'Age Category',
raceCategory: 'Race', diabetic: 'Diabetic', physicalActivity: 'Physical Activity',
genHealth: 'General Health', sleepTime: 'Sleep Time', asthma: 'Asthma',
kidneyDisease: 'Kidney Disease', skinCancer: 'Skin Cancer'
};
const formatLabel = label => labelMap[label] || label;
const svg = d3.create('svg')
.attr('viewBox', `0 0 ${chartWidth} ${chartHeight}`)
.attr('preserveAspectRatio', 'xMidYMid meet')
.style('width', '100%')
.style('height', 'auto');
svg.selectAll('rect')
.data(correlationMatrix)
.enter()
.append('rect')
.attr('x', d => xScale(d.target))
.attr('y', d => yScale(d.factor))
.attr('width', xScale.bandwidth())
.attr('height', yScale.bandwidth())
.attr('fill', d => colorScale(d.correlation));
svg.selectAll('text')
.data(correlationMatrix)
.enter()
.append('text')
.attr('x', d => xScale(d.target) + xScale.bandwidth() / 2)
.attr('y', d => yScale(d.factor) + yScale.bandwidth() / 2)
.attr('dy', '.40em')
.attr('text-anchor', 'middle')
.text(d => d3.format('.2f')(d.correlation))
.attr('fill', 'black')
.style('font-family', 'Arial, sans-serif')
.style('font-size', '14px');
svg.append('g')
.attr('transform', `translate(0, ${margin.top})`)
.call(d3.axisTop(xScale))
.selectAll('text')
.style('text-anchor', 'middle')
.style('font-size', '12px')
.text(d => formatLabel(d));
svg.append('g')
.attr('transform', `translate(${margin.left}, 0)`)
.call(d3.axisLeft(yScale))
.selectAll('text')
.style('font-size', '12px')
.text(d => formatLabel(d));
const legendHeight = 20;
const legendWidth = 300;
const legend = svg.append('g')
.attr('transform', `translate(${(chartWidth - legendWidth) / 2}, ${chartHeight - margin.bottom + 30})`);
const gradient = legend.append('defs')
.append('linearGradient')
.attr('id', 'gradient')
.attr('x1', '0%')
.attr('x2', '100%')
.attr('y1', '0%')
.attr('y2', '0%');
gradient.append('stop')
.attr('offset', '0%')
.attr('stop-color', "#61b8e7");
gradient.append('stop')
.attr('offset', '100%')
.attr('stop-color', "#d23626");
legend.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', legendWidth)
.attr('height', legendHeight)
.style('fill', 'url(#gradient)');
legend.append('text')
.attr('x', 0)
.attr('y', legendHeight + 15)
.attr('dy', '.35em')
.attr('text-anchor', 'middle')
.style('font-family', 'Arial, sans-serif')
.style('font-size', '12px')
.text('Neg. Correlation (-1.0)')
.attr('fill', 'black');
legend.append('text')
.attr('x', legendWidth)
.attr('y', legendHeight + 15)
.attr('dy', '.35em')
.attr('text-anchor', 'middle')
.style('font-family', 'Arial, sans-serif')
.style('font-size', '12px')
.text('Pos. Correlation (1.0)')
.attr('fill', 'black');
svg.append('text')
.attr('x', chartWidth / 2)
.attr('y', margin.top / 2)
.attr('text-anchor', 'middle')
.attr('font-family', 'Arial, sans-serif')
.attr('font-size', '25px')
.attr('font-weight', 'bold')
.text('Correlation Between Health Factors and Disease');
return svg.node();
}