在 chart.js 中更改图例框的颜色和 x 网格线的颜色
Change the color of the legend box and the color of the x grid lines in chart.js
大家好:
最近我开始使用 Vue.js(2.6.12) + Vuetify(2.3.10) 和 Chart.js(3.0.2)。所以我(又)是新手了。
我创建了一个组件,它包装了 Chart.js 允许我们创建的条形图。这是它的照片:
我唯一想要更改的两件事是靠近图例标题的小框和一些网格 x 线。
在小图例的情况下方框是红色的。我希望它与图例标题文本的蓝色对齐。正如我在这张图片中向您展示的那样:
最后我想在 X 轴上添加一些颜色(粉红色):
我做不到。我已经关注并遵循了官方文档,但没有任何效果:S.
- 创建用颜色绘制一些轴的函数:https://www.chartjs.org/docs/3.0.2/samples/scale-options/grid.html
- 更改图例的颜色:https://www.chartjs.org/docs/3.0.2/configuration/legend.html#legend-label-configuration
在图例标题框的情况下,我注意到它始终采用第一个元素的颜色。
在轴的情况下,chart.js 支持的功能对我不起作用。它根本不打印 x 轴。
我尝试过的事情:
- 升级到 chart.js 3.3.0 但我收到这样的错误:“”
我使用 3.0.2 的原因是因为它是唯一的版本
从 3.0.0 版本开始为我工作。
- 降级到 2.9.3/4。我无法更改框的颜色或轴线,但其余的工作正常。
- 使用包装器:https://vue-chartjs.org/。没用
整个组件代码:
<template>
<div class="container pa-3" fill-height fluid style="width: 100%">
<!-- We create the chart -->
<canvas id="myChart1" />
</div>
</template>
<script>
import Chart from "chart.js/auto";
export default {
name: "Chart",
components: {},
props: {},
data: () => ({
ctx: null,
myChart: null,
type: "bar",
data: {
labels: ["a", "b", "c", "d"],
datasets: [
{
data: [1, 2, 3, 4],
backgroundColor: ["#c30", "#e37609", "#ffda05", "#fffb05"],
},
],
},
options: {
plugins: {
legend: {
display: true,
labels: {
color: "#00a3fb",
},
},
},
scales: {
},
},
}),
methods: {
createChart: function () {
// destroy the previous graph
if (this.myChart != null) this.myChart.destroy();
// create a new one
this.ctx = document.getElementById("myChart1");
this.myChart = new Chart(this.ctx, {
type: this.type,
data: this.data,
options: this.options,
});
this.myChart.render();
},
},
destroyed() {},
mounted() {
this.createChart();
},
watch: {},
};
</script>
<style scoped>
</style>
要使用它,您应该:
- 在节中导入它
- 在组件部分声明它
- 通过
<NameOfComponetGiven/>
标签调用
非常感谢任何帮助。
非常感谢。
要自定义图例框颜色,您需要使用自定义 HTML 图例,在那里您可以使用 CSS 指定它,对于粉红色网格线,您可以使用脚本选项。对于两者,请参见示例:
const getOrCreateLegendList = (chart, id) => {
const legendContainer = document.getElementById(id);
let listContainer = legendContainer.querySelector('ul');
if (!listContainer) {
listContainer = document.createElement('ul');
listContainer.style.display = 'flex';
listContainer.style.flexDirection = 'row';
listContainer.style.margin = 0;
listContainer.style.padding = 0;
legendContainer.appendChild(listContainer);
}
return listContainer;
};
const htmlLegendPlugin = {
id: 'htmlLegend',
afterUpdate(chart, args, options) {
const ul = getOrCreateLegendList(chart, options.containerID);
// Remove old legend items
while (ul.firstChild) {
ul.firstChild.remove();
}
// Reuse the built-in legendItems generator
const items = chart.options.plugins.legend.labels.generateLabels(chart);
items.forEach(item => {
const li = document.createElement('li');
li.style.alignItems = 'center';
li.style.cursor = 'pointer';
li.style.display = 'flex';
li.style.flexDirection = 'row';
li.style.marginLeft = '10px';
li.onclick = () => {
const {
type
} = chart.config;
if (type === 'pie' || type === 'doughnut') {
// Pie and doughnut charts only have a single dataset and visibility is per item
chart.toggleDataVisibility(item.index);
} else {
chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
}
chart.update();
};
// Color box
const boxSpan = document.createElement('span');
boxSpan.style.background = options.legendBoxColor || item.fillStyle;
boxSpan.style.borderColor = item.strokeStyle;
boxSpan.style.borderWidth = item.lineWidth + 'px';
boxSpan.style.display = 'inline-block';
boxSpan.style.height = '20px';
boxSpan.style.marginRight = '10px';
boxSpan.style.width = '20px';
// Text
const textContainer = document.createElement('p');
textContainer.style.color = options.legendTextColor || item.fontColor;
textContainer.style.margin = 0;
textContainer.style.padding = 0;
textContainer.style.textDecoration = item.hidden ? 'line-through' : '';
const text = document.createTextNode(item.text);
textContainer.appendChild(text);
li.appendChild(boxSpan);
li.appendChild(textContainer);
ul.appendChild(li);
});
}
};
const options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
backgroundColor: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"]
}]
},
options: {
scales: {
x: {
grid: {
color: (line) => ((line.index === 2 || line.index === 3) ? 'pink' : 'rgba(0,0,0,0.1)'),
lineWidth: (line) => ((line.index === 2 || line.index === 3) ? 6 : 1)
}
}
},
plugins: {
htmlLegend: {
// ID of the container to put the legend in
containerID: 'legendContainer',
legendBoxColor: 'blue',
legendTextColor: 'blue'
},
legend: {
display: false,
}
}
},
plugins: [htmlLegendPlugin]
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<div id="legendContainer"></div>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.0.2/chart.js"></script>
</body>
大家好:
最近我开始使用 Vue.js(2.6.12) + Vuetify(2.3.10) 和 Chart.js(3.0.2)。所以我(又)是新手了。
我创建了一个组件,它包装了 Chart.js 允许我们创建的条形图。这是它的照片:
我唯一想要更改的两件事是靠近图例标题的小框和一些网格 x 线。
在小图例的情况下方框是红色的。我希望它与图例标题文本的蓝色对齐。正如我在这张图片中向您展示的那样:
最后我想在 X 轴上添加一些颜色(粉红色):
我做不到。我已经关注并遵循了官方文档,但没有任何效果:S.
- 创建用颜色绘制一些轴的函数:https://www.chartjs.org/docs/3.0.2/samples/scale-options/grid.html
- 更改图例的颜色:https://www.chartjs.org/docs/3.0.2/configuration/legend.html#legend-label-configuration
在图例标题框的情况下,我注意到它始终采用第一个元素的颜色。 在轴的情况下,chart.js 支持的功能对我不起作用。它根本不打印 x 轴。
我尝试过的事情:
- 升级到 chart.js 3.3.0 但我收到这样的错误:“” 我使用 3.0.2 的原因是因为它是唯一的版本 从 3.0.0 版本开始为我工作。
- 降级到 2.9.3/4。我无法更改框的颜色或轴线,但其余的工作正常。
- 使用包装器:https://vue-chartjs.org/。没用
整个组件代码:
<template>
<div class="container pa-3" fill-height fluid style="width: 100%">
<!-- We create the chart -->
<canvas id="myChart1" />
</div>
</template>
<script>
import Chart from "chart.js/auto";
export default {
name: "Chart",
components: {},
props: {},
data: () => ({
ctx: null,
myChart: null,
type: "bar",
data: {
labels: ["a", "b", "c", "d"],
datasets: [
{
data: [1, 2, 3, 4],
backgroundColor: ["#c30", "#e37609", "#ffda05", "#fffb05"],
},
],
},
options: {
plugins: {
legend: {
display: true,
labels: {
color: "#00a3fb",
},
},
},
scales: {
},
},
}),
methods: {
createChart: function () {
// destroy the previous graph
if (this.myChart != null) this.myChart.destroy();
// create a new one
this.ctx = document.getElementById("myChart1");
this.myChart = new Chart(this.ctx, {
type: this.type,
data: this.data,
options: this.options,
});
this.myChart.render();
},
},
destroyed() {},
mounted() {
this.createChart();
},
watch: {},
};
</script>
<style scoped>
</style>
要使用它,您应该:
- 在节中导入它
- 在组件部分声明它
- 通过
<NameOfComponetGiven/>
标签调用
非常感谢任何帮助。 非常感谢。
要自定义图例框颜色,您需要使用自定义 HTML 图例,在那里您可以使用 CSS 指定它,对于粉红色网格线,您可以使用脚本选项。对于两者,请参见示例:
const getOrCreateLegendList = (chart, id) => {
const legendContainer = document.getElementById(id);
let listContainer = legendContainer.querySelector('ul');
if (!listContainer) {
listContainer = document.createElement('ul');
listContainer.style.display = 'flex';
listContainer.style.flexDirection = 'row';
listContainer.style.margin = 0;
listContainer.style.padding = 0;
legendContainer.appendChild(listContainer);
}
return listContainer;
};
const htmlLegendPlugin = {
id: 'htmlLegend',
afterUpdate(chart, args, options) {
const ul = getOrCreateLegendList(chart, options.containerID);
// Remove old legend items
while (ul.firstChild) {
ul.firstChild.remove();
}
// Reuse the built-in legendItems generator
const items = chart.options.plugins.legend.labels.generateLabels(chart);
items.forEach(item => {
const li = document.createElement('li');
li.style.alignItems = 'center';
li.style.cursor = 'pointer';
li.style.display = 'flex';
li.style.flexDirection = 'row';
li.style.marginLeft = '10px';
li.onclick = () => {
const {
type
} = chart.config;
if (type === 'pie' || type === 'doughnut') {
// Pie and doughnut charts only have a single dataset and visibility is per item
chart.toggleDataVisibility(item.index);
} else {
chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
}
chart.update();
};
// Color box
const boxSpan = document.createElement('span');
boxSpan.style.background = options.legendBoxColor || item.fillStyle;
boxSpan.style.borderColor = item.strokeStyle;
boxSpan.style.borderWidth = item.lineWidth + 'px';
boxSpan.style.display = 'inline-block';
boxSpan.style.height = '20px';
boxSpan.style.marginRight = '10px';
boxSpan.style.width = '20px';
// Text
const textContainer = document.createElement('p');
textContainer.style.color = options.legendTextColor || item.fontColor;
textContainer.style.margin = 0;
textContainer.style.padding = 0;
textContainer.style.textDecoration = item.hidden ? 'line-through' : '';
const text = document.createTextNode(item.text);
textContainer.appendChild(text);
li.appendChild(boxSpan);
li.appendChild(textContainer);
ul.appendChild(li);
});
}
};
const options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
backgroundColor: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"]
}]
},
options: {
scales: {
x: {
grid: {
color: (line) => ((line.index === 2 || line.index === 3) ? 'pink' : 'rgba(0,0,0,0.1)'),
lineWidth: (line) => ((line.index === 2 || line.index === 3) ? 6 : 1)
}
}
},
plugins: {
htmlLegend: {
// ID of the container to put the legend in
containerID: 'legendContainer',
legendBoxColor: 'blue',
legendTextColor: 'blue'
},
legend: {
display: false,
}
}
},
plugins: [htmlLegendPlugin]
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<div id="legendContainer"></div>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.0.2/chart.js"></script>
</body>