В настоящее время мои галочки выравниваются следующим образом:
И я бы хотел, чтобы они были выровнены таким образом, а текст выровнен по вертикали следующим образом:
Я пробовал несколько разных вариантов, где визуально он был бы выровнен, но не проходит тесты, так как идентификаторы каждой отдельной ячейки не выровнены со значениями на оси Y. Я не уверен, как бы я это сделал. Вот моя кодовая ссылка
const addMonthStrings = dataset => {
for (let i=0; i < dataset.length; i++) {
let newPropName = 'monthStr';
switch (dataset[i]['month']) {
case 1:
dataset[i][newPropName] = 'January';
break;
case 2:
dataset[i][newPropName] = 'February';
break;
case 3:
dataset[i][newPropName] = 'March';
break;
case 4:
dataset[i][newPropName] = 'April';
break;
case 5:
dataset[i][newPropName] = 'May';
break;
case 6:
dataset[i][newPropName] = 'June';
break;
case 7:
dataset[i][newPropName] = 'July';
break;
case 8:
dataset[i][newPropName] = 'August';
break;
case 9:
dataset[i][newPropName] = 'September';
break;
case 10:
dataset[i][newPropName] = 'October';
break;
case 11:
dataset[i][newPropName] = 'November';
break;
case 12:
dataset[i][newPropName] = 'December';
break;
};
};
};
const tempColoring = (currTemp, colorPalette) => {
if (currTemp <= 2.8) {
return colorPalette.color1;
} else if (currTemp > 2.8 && currTemp <= 3.9) {
return colorPalette.color2;
} else if (currTemp > 3.9 && currTemp <= 5.0) {
return colorPalette.color3;
} else if (currTemp > 5.0 && currTemp <= 6.1) {
return colorPalette.color4;
} else if (currTemp > 6.1 && currTemp <= 7.2) {
return colorPalette.color5;
} else if (currTemp > 7.2 && currTemp <= 8.3) {
return colorPalette.color6;
} else if (currTemp > 8.3 && currTemp <= 9.5) {
return colorPalette.color7;
} else if (currTemp > 9.5 && currTemp <= 10.6) {
return colorPalette.color8;
} else if (currTemp > 10.6 && currTemp <= 11.7) {
return colorPalette.color9;
} else if (currTemp > 11.7 && currTemp <= 12.8) {
return colorPalette.color10;
} else {
return colorPalette.color11;
}
};
const render = (baseTemperature, dataset) => {
const width = 960;
const height = 500;
const xValue = d => d['year'];
const yValue = d => d['month'] - 1;
const monthStr = d => d['monthStr'];
const variance = d => Math.round(d['variance'] * 10) / 10;
const currTemp = d => Math.round((baseTemperature + d['variance']) * 10) / 10;
const margin = { top: 110, right: 60, bottom: 120, left: 100 };
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const minYear = d3.min(dataset, xValue);
const maxYear = d3.max(dataset, xValue);
const yearRange = maxYear - minYear;
const minMonth = d3.min(dataset, yValue);
const maxMonth = d3.max(dataset, yValue);
const cellWidth = innerWidth / yearRange;
const cellHeight = innerHeight / 12;
const xAxisLabelText = 'Years';
const xAxisLabelXPos = innerWidth / 2;
const xAxisLabelYPos = 40;
const yAxisLabelText = 'Months';
const yAxisLabelXPos = -innerHeight / 2;
const yAxisLabelYPos = -70;
const titleText = 'Monthly Global Land-Surface Temperature';
const titleXAxisPos = width / 2;
const titleYAxisPos = 40;
const subtitleText = `${minYear} - ${maxYear}: base temperature ${baseTemperature}℃`;
const subtitleYAxisPos = titleYAxisPos + 22;
const colorPalette = {
'color1': 'rgb(49, 54, 149)',
'color2': 'rgb(69, 117, 180)',
'color3': 'rgb(116, 173, 209)',
'color4': 'rgb(171, 217, 233)',
'color5': 'rgb(224, 243, 248)',
'color6': 'rgb(255, 255, 191)',
'color7': 'rgb(254, 224, 144)',
'color8': 'rgb(253, 174, 97)',
'color9': 'rgb(244, 109, 67)',
'color10': 'rgb(215, 48, 39)',
'color11': 'rgb(165, 0, 38)'
}; // Colors will be assigned correspondingly to the increase in temp (1 - coldest, 11 - warmest)
// Initiate a svg canvas
const svg = d3.select('body')
.append('svg')
.style('height', height)
.style('width', width)
// Initiate a heat map
const heatmap = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
// Establish a scale
const xScale = d3.scaleTime()
.domain([minYear - 1, maxYear])
.range([0, innerWidth]);
const yScale = d3.scaleTime()
.domain([minMonth, maxMonth])
.range([0, innerHeight]);
// Create axes
const xAxis = d3.axisBottom(xScale).tickFormat(d => d3.timeFormat('%Y')( new Date(0).setFullYear(d) ));
const yAxis = d3.axisLeft(yScale).tickFormat(d => d3.timeFormat('%B')( new Date(0).setMonth(d) ));
const xAxisG = heatmap.append('g')
.attr('id', 'x-axis')
.attr('transform', `translate(0, ${innerHeight})`)
.call(xAxis);
xAxisG.append('text')
.attr('id', 'xAxis-label')
.attr('x', xAxisLabelXPos)
.attr('y', xAxisLabelYPos)
.attr('fill', 'black')
.attr('text-anchor', 'middle')
.style('font-size', '1.5em')
.text(xAxisLabelText)
const yAxisG = heatmap.append('g')
.attr('id', 'y-axis')
.attr('transform', `translate(0, 0)`)
.call(yAxis);
yAxisG.append('text')
.attr('id', 'yAxis-label')
.attr('x', yAxisLabelXPos)
.attr('y', yAxisLabelYPos)
.attr('fill', 'black')
.attr('transform', 'rotate(-90)')
.attr('text-anchor', 'middle')
.style('font-size', '1.5em')
.text(yAxisLabelText)
const titleSection = svg.append('g')
.attr('text-anchor', 'middle')
titleSection.append('text')
.attr('id', 'title')
.attr('x', titleXAxisPos)
.attr('y', titleYAxisPos)
.style('font-size', '1.5em')
.style('font-weight', 'bold')
.text(titleText);
titleSection.append('text')
.attr('id', 'description')
.attr('x', titleXAxisPos)
.attr('y', subtitleYAxisPos)
.style('font-size', '1.2em')
.text(subtitleText);
let tooltip = d3.select('body').append('div')
.attr('id', 'tooltip')
.style('opacity', 0)
// Append cells to the heatmap
heatmap.selectAll('rect').data(dataset)
.enter().append('rect')
.attr('x', d => xScale(xValue(d)))
.attr('y', d => yScale(yValue(d)) - cellHeight)
.attr('width', cellWidth)
.attr('height', cellHeight)
.attr('fill', d => tempColoring(currTemp(d), colorPalette)) //fill with palette accordingly
.attr('class', 'cell')
.attr('data-year', d => xValue(d))
.attr('data-month', d => yValue(d))
.attr('data-temp', d => currTemp(d))
.on('mouseover', d => {
tooltip.transition().duration(200).style('opacity', 0.9);
tooltip.html(`${xValue(d)} - ${monthStr(d)}
</br>${currTemp(d)}°C
</br>${variance(d)}°C`)
.style('left', d3.event.pageX + 'px')
.style('top', d3.event.pageY + 'px')
.attr('data-year', xValue(d));
})
.on('mouseout', d => {
tooltip.transition().duration(500).style('opacity', 0);
});
/*
const legendWidth = 200;
const legendSquareWidth = legendWidth / 11;
const legend = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top + 80})`);
const tempScale = d3.scaleLinear()
.domain([d3.min(dataset, currTemp), d3.max(dataset, currTemp)])
.range([0, legendWidth]);
const xAxisLegend = d3.axisBottom(tempScale);
legend.append('g')
.attr('id', 'legend-x-axis')
.attr('transform', `translate(0, ${innerHeight})`)
.call(xAxisLegend);
/*
legend.selectAll('rect').data(dataset)
.enter().append('rect')
.attr('x', (d, i) => i)
.attr('y', d => yScale(yValue(d)))
.attr('width', 10)
.attr('height', 20) */
};
document.addEventListener('DOMContentLoaded', function() {
const request = new XMLHttpRequest();
request.open('GET', 'https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/global-temperature.json', true);
request.send();
request.onload = function () {
let json = JSON.parse(request.responseText);
let baseTemperature = json.baseTemperature;
let dataset = json.monthlyVariance;
addMonthStrings(dataset);
render(baseTemperature, dataset);
};
});
body {
background-color: rgb(229, 226, 224);
font-family: monospace;
}
svg {
background-color: white;
position: absolute;
top: 50%;
left: 50%;
-moz-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
#tooltip {
position: relative;
text-align: center;
width: 120px;
border: 1px solid rgb(97, 94, 84);
border-radius: 10px;
background: rgb(229, 226, 224);
padding: 10px;
}
.cell:hover {
stroke: black;
stroke-width: 0.8;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script>
<script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
<body></body>