我正在使用ChartJS制作图表。一切都进行得很顺利,但有一个例外:尽管正在绘制X轴线(沿图表底部水平延伸的线),但是Y轴线(沿图表垂直方向延伸的线)却没有,尽管我已经应用了几乎相同的配置。
我对此进行了广泛的尝试,无法弄清楚我在做什么错。
我快要尝试做些棘手的事情了(基本上,在尝试使用容器确定其长度和位置后,绝对要在图表上方放置一条线-有点噩梦),但是我想看看这里是否有人对ChartJS更加熟悉,可能会对我做错了。
Here's the CodePen(其余文章下方的JS)。
下面是the styling documentation,我正在尝试使其正常运行。 (请参见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,
});
答案 0 :(得分:1)
不确定为什么选项zeroLineColor
适用于一个轴,而不适用于另一个轴。
但是我们可以为网格线使用颜色数组,
将第一个设置为白色,其余设置为透明。
请参阅以下工作片段...
$(document).ready(function() {
// 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 transparent = 'transparent';
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: {
color: points.map((_, ind) =>
ind === 0
? white
: transparent
),
lineWidth: 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,
});
});
.container {
/* squidInk - matches JS */
background-color: #232F3E;
position: relative;
width: 100%;
}
.section-label {
color: white;
font-size: 20px;
position: absolute;
}
.section-label.upper {
left: 100px;
top: 60px;
}
.section-label.lower {
right: 60px;
bottom: 60px;
}
#chartjs-tooltip div {
position: absolute;
left: -10px;
top: -10px;
cursor: pointer;
}
#chartjs-tooltip .percent-tooltip {
font-size: 20px;
font-weight: bold;
display: block;
position: absolute;
color: white;
}
#chartjs-tooltip span.percent-tooltip.external {
top: -30px;
}
#chartjs-tooltip span.percent-tooltip.sellers {
top: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<div class="container">
<span class="section-label upper">Internal</span>
<canvas id="chart" width="300" height="150"></canvas>
<span class="section-label lower">External</span>
</div>