Я делаю график, используя ChartJS. Все прошло гладко, за одним исключением: хотя линия оси X (линия, которая проходит горизонтально вдоль основания диаграммы) рисуется, линия оси Y (та, которая проходит вертикально вдоль левой части) нет, даже хотя я применил почти идентичные конфигурации.
Я много играл с этим и не могу понять, что я делаю не так.
Я пытаюсь сделать что-то хакерское (по сути, абсолютно позиционирую линию на вершине графика, после попытки использовать контейнер для определения его длины и местоположения - немного кошмар), но я хотел чтобы увидеть, может ли кто-нибудь здесь, кто был более знаком с ChartJS, иметь представление о том, что я делаю неправильно.
Вот CodePen (JS ниже остальной части поста).
А вот документация по стилю Я следовал, чтобы попытаться заставить его работать. (См. Значения zeroLineWidth и zeroLineColor).
Есть идеи, что я делаю не так или как это исправить?
// Colors
const squidInk = '#232F3E'; // Background and hover circle interior
const mermaid = '#00A4B4'; // Gridlines
const siren = '#0099D9'; // Line and points
const darkGrey = '#3A444F'; // Fill below line - NOTE: doesn't seem to be one of main colors
const white = '#FFF'; // Font white - in one place to change globally (sync w CSS)
const mobileBreakpoint = 768;
const isMobile = window.innerWidth <= mobileBreakpoint;
// Helper for below tooltip generation
const getTooltipStyles = (tooltipModel, position) => ({
opacity: 1,
position: 'absolute',
left: position.left + window.pageXOffset + tooltipModel.caretX + 'px',
top: position.top + window.pageYOffset + tooltipModel.caretY + 'px',
fontFamily: tooltipModel._bodyFontFamily,
fontSize: tooltipModel.bodyFontSize + 'px',
fontStyle: tooltipModel._bodyFontStyle,
padding: tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px',
pointerEvents: 'none'
});
// Chart points (y-coords; there are 20).
// Loosely approximates the data in the designs.
const points = [
4, 4, 8, 19, 22,
25, 27, 27, 28, 30,
32, 34, 40, 44, 46,
48, 52, 53, 55, 57
];
// The value of the data key in the Chart config.
// Contains points in the main (only) dataset,
// and related configuration.
const data = {
// Years from 1997 to 2016.
// Hide all but first and last label on mobile
labels: points.map((_, ind) =>
isMobile && ![0, points.length - 1].includes(ind)
? ''
: 1997 + ind
),
datasets: [{
data: points,
fill: true,
backgroundColor: darkGrey,
borderColor: siren,
borderWidth: 4,
pointHitRadius: 20,
pointRadius: isMobile ? 0 : 2,
pointHoverRadius: isMobile ? 0 : 10,
pointHoverBackgroundColor: squidInk,
pointHoverBorderWidth: 3
}]
};
// Function to replace the tooltip with custom HTML.
// NOTE: This needs to be a function, not a const, because of how
// `this` is bound.
function customTooltip (tooltipModel) {
if (isMobile) {
return '';
}
// Tooltip Element
let tooltipEl = document.getElementById('chartjs-tooltip');
// Create element on first render
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = '<div></div>';
document.body.appendChild(tooltipEl);
}
// Hide if no tooltip
if (tooltipModel.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set caret Position
tooltipEl.classList.remove('above', 'below', 'no-transform');
tooltipEl.classList.add(
tooltipModel.yAlign
? tooltipModel.yAlign
: 'no-transform'
);
// Set Text
if (tooltipModel.body) {
const titleLines = tooltipModel.title || [];
const bodyLines = tooltipModel.body.map(bodyItem => bodyItem.lines);
// Text for hover percentages
const percentExternal = bodyLines[0];
const percentSellers = 100 - percentExternal;
// These spans are styled in the CSS
const innerHtml = `
<span class="percent-tooltip external">${percentExternal}%</span>
<span class="percent-tooltip sellers">${percentSellers}%</span>
`;
const root = tooltipEl.querySelector('div');
root.innerHTML = innerHtml;
}
// `this` will be the overall tooltip
const position = this._chart.canvas.getBoundingClientRect();
// Apply positional styles to the tooltip (cleaned up and put above for clarity)
const styles = getTooltipStyles(tooltipModel, position);
Object.keys(styles).forEach(k => tooltipEl.style[k] = styles[k]);
};
// High-level chart options
const options = {
legend: {
display: false
},
tooltips: {
enabled: false,
custom: customTooltip // Custom tooltip func (above)
},
scales: {
yAxes: [{
ticks: {
// Include a percentage sign in the ticks.
// Hide zero label on mobile.
callback: value => isMobile ? (value ? `${value}%` : '') : `${value}%`,
fontColor: white,
max: 100,
stepSize: isMobile ? 50 : 25
},
scaleLabel: {
display: !isMobile,
labelString: '% OF MERCHANDISE SALES',
fontColor: white
},
gridLines: {
color: mermaid,
zeroLineColor: white,
zeroLineWidth: 2,
drawBorder: false
}
}],
xAxes: [{
gridLines: {
drawOnChartArea: false,
// The x zero-line isn't painting! Maybe because it's not at zero (but at 1997)?
// NOTE: I tried fixing this by messing with the data, so that the x-axis included 0, but that didn't work.
zeroLineColor: white,
zeroLineWidth: 2
},
ticks: {
fontColor: white
}
}]
}
};
// Find the div to insert the chart into
const ctx = document.getElementById('chart').getContext('2d');
// And generate the chart
const chart = new Chart(ctx, {
type: 'line',
data,
options,
});