我对我的chartjs图表应用了一些渐变规则。正如您在下面看到的那样,它看起来很棒
但是,当调整浏览器窗口的大小(即窗口的宽度较小)时,渐变会破坏(底部的蓝色消失)。截图:
我想用所有值保持图形的渐变并适合不同的宽度(响应)。有什么办法吗?这是我尝试过但无法使用的内容:
.TS文件
ngAfterViewInit() {
const ctx = (<HTMLCanvasElement>this.myChart.nativeElement).getContext('2d');
const purple_orange_gradient = ctx.createLinearGradient(0, 200, 0, 20);
purple_orange_gradient.addColorStop(0.1, "#000279");
purple_orange_gradient.addColorStop(0.2, "#0000F2");
purple_orange_gradient.addColorStop(0.3, "#0362FD");
purple_orange_gradient.addColorStop(0.4, "#04D3FD");
purple_orange_gradient.addColorStop(0.5, "#45FFB7");
purple_orange_gradient.addColorStop(0.6, "#B7FF46");
purple_orange_gradient.addColorStop(0.7, "#FFD401");
purple_orange_gradient.addColorStop(0.8, "#FE6500");
purple_orange_gradient.addColorStop(0.9, "#F30004");
purple_orange_gradient.addColorStop(1, "#7E0100");
const bar_chart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: []=this.histogramLabels.reverse(),
datasets: [{
borderColor: purple_orange_gradient,
pointBorderColor: purple_orange_gradient,
pointBackgroundColor: purple_orange_gradient,
pointHoverBackgroundColor: purple_orange_gradient,
pointHoverBorderColor: purple_orange_gradient,
pointBorderWidth: 10,
pointHoverRadius: 10,
pointHoverBorderWidth: 1,
pointRadius: 3,
fill: true,
backgroundColor: purple_orange_gradient,
borderWidth: 4,
data: []=this.histogramGraphData
}]
},
options: {
legend: {
display:false,
position: "bottom"
},
scales: {
yAxes: [{
ticks: {
display: false,
fontColor: "rgba(0,0,0,0.5)",
fontStyle: "bold",
beginAtZero: true,
maxTicksLimit: 1,
padding: 20,
},
gridLines: {
drawTicks: false,
display: false
}
}],
xAxes: [{
gridLines: {
zeroLineColor: "transparent",
},
ticks: {
padding: 20,
beginAtZero: true,
fontColor: "rgba(0,0,0,0.5)",
fontStyle: "bold"
}
}]
}
}
}
)
}
.HTML
<div class="row my-2">
<div class="col-md-6">
<canvas id=”myChart” #myChart height="130"></canvas>
</div>
</div>
答案 0 :(得分:1)
每当画布调整大小时,都必须更改渐变。花了我一段时间来找出一个好的结构,以减少代码行并优化性能。这是我能达到的最好成绩。
虽然chart.js
onResize()
被解雇了,但我无法完全解决这个问题。但是对于简单的调整大小,它应该可以工作。
完整代码(same code in JSBin with live preview):
let sData = {}
sData.labels = []
sData.data = []
const count = 50
for (let x = 0; x < count; x++) {
sData.data.push(Math.floor(Math.random()*100))
sData.labels.push(x)
}
const canvas = document.getElementById('chart')
const ctx = canvas.getContext("2d")
let purple_orange_gradient
function updateGradient() {
let bottom = bar_chart.chartArea.bottom
let top = bar_chart.chartArea.top
purple_orange_gradient = ctx.createLinearGradient(0, bottom+top, 0, top)
purple_orange_gradient.addColorStop(0.1, "#000279")
purple_orange_gradient.addColorStop(0.2, "#0000F2")
purple_orange_gradient.addColorStop(0.3, "#0362FD")
purple_orange_gradient.addColorStop(0.4, "#04D3FD")
purple_orange_gradient.addColorStop(0.5, "#45FFB7")
purple_orange_gradient.addColorStop(0.6, "#B7FF46")
purple_orange_gradient.addColorStop(0.7, "#FFD401")
purple_orange_gradient.addColorStop(0.8, "#FE6500")
purple_orange_gradient.addColorStop(0.9, "#F30004")
purple_orange_gradient.addColorStop(1.0, "#7E0100")
return purple_orange_gradient
}
const bar_chart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: sData.labels,
datasets: [{
borderColor: purple_orange_gradient,
pointBorderColor: purple_orange_gradient,
pointBackgroundColor: purple_orange_gradient,
pointHoverBackgroundColor: purple_orange_gradient,
pointHoverBorderColor: purple_orange_gradient,
pointBorderWidth: 10,
pointHoverRadius: 10,
pointHoverBorderWidth: 1,
pointRadius: 3,
fill: true,
backgroundColor: purple_orange_gradient,
borderWidth: 4,
data: sData.data
}]
},
options: {
legend: {
display: false,
position: "bottom"
},
scales: {
yAxes: [{
ticks: {
display: false,
fontColor: "rgba(0,0,0,0.5)",
fontStyle: "bold",
beginAtZero: true,
maxTicksLimit: 1,
padding: 20,
},
gridLines: {
drawTicks: false,
display: false
}
}],
xAxes: [{
gridLines: {
zeroLineColor: "transparent",
},
ticks: {
padding: 20,
beginAtZero: true,
fontColor: "rgba(0,0,0,0.5)",
fontStyle: "bold"
}
}]
},
onResize: function(chart, size) {
// onResize gradient change
changeGradient()
}
}
});
// Initial gradient change
changeGradient()
function changeGradient() {
let newGradient = updateGradient()
bar_chart.data.datasets[0].borderColor = newGradient
bar_chart.data.datasets[0].pointBorderColor = newGradient
bar_chart.data.datasets[0].pointBackgroundColor = newGradient
bar_chart.data.datasets[0].pointHoverBackgroundColor = newGradient
bar_chart.data.datasets[0].pointHoverBorderColor = newGradient
bar_chart.data.datasets[0].backgroundColor = newGradient
bar_chart.update()
}
答案 1 :(得分:1)
HTML Canvas的createLinearGradient()
取决于您作为参数传递的y
轴坐标。您每次都传递了静态200(即ctx.createLinearGradient(0, 200, 0, 20);
)。
这就是为什么渐变步长每次都保持不变的原因。为了更新渐变,您必须重新计算窗口调整大小时<canvas>
元素的 height ,然后再次将其传递到createLinearGradient()
。
您可以通过以下方式完成此操作:
eleHeight
检索canvas元素的高度。 generateGradient(){
let eleHeight = this.myChart.nativeElement.offsetHeight;
// console.log(eleHeight)
let purple_orange_gradient: CanvasGradient = this.myChart.nativeElement.getContext('2d').createLinearGradient(0, eleHeight, 0, 20);
purple_orange_gradient.addColorStop(0.1, "#000279");
purple_orange_gradient.addColorStop(0.2, "#0000F2");
purple_orange_gradient.addColorStop(0.3, "#0362FD");
purple_orange_gradient.addColorStop(0.4, "#04D3FD");
purple_orange_gradient.addColorStop(0.5, "#45FFB7");
purple_orange_gradient.addColorStop(0.6, "#B7FF46");
purple_orange_gradient.addColorStop(0.7, "#FFD401");
purple_orange_gradient.addColorStop(0.8, "#FE6500");
purple_orange_gradient.addColorStop(0.9, "#F30004");
purple_orange_gradient.addColorStop(1, "#7E0100");
return purple_orange_gradient;
}
<div>
的事件处理程序中,然后再次生成渐变。 您还需要在每次更改时以编程方式更新图表以重新呈现。 <div style="display: block; max-height: 100%" (window:resize)="onResize($event)" >
...
</div>
onResize(event?){
// console.log("onResize");
this.barChartData.forEach((d, i) => {
d.backgroundColor = this.generateGradient();
})
this.chart.chart.update(); //update the chart to re-render it
}
barchartData
中ngAfterViewInit
的属性(使用渐变)。我们在这里需要这样做,因为我们只希望填充数据的<canvas>
元素的高度。如果不填充数据,则元素会小得多。 ngAfterViewInit(){
this.barChartData.forEach((d, i) => {
d.backgroundColor = this.generateGradient();
});
this.chart.chart.update(); //update the chart to re-render it
}
看看我创建的这个 Stackblitz example⚡⚡ 。