En un gráfico de chartjs, la función se ejecuta varias veces (aproximadamente 25), ¿cómo puedo reducir eso?
Aquí hay un violín que consola la cantidad de veces que se ejecuta: https://jsfiddle.net/abhishek_soni/38mfez7g/26/
Aquí está el código:
var ctx = document.getElementById('myChart').getContext('2d'); let i=0, j=0, k=0; var myChart = new Chart(ctx, { type: 'line', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: function() { ++i; console.log('why this bordercolor running this many times : ', i) return 'green' }, borderWidth: 1 }] }, options: { responsive: function() { k++; console.log('why this option running this many times : ', k) return false }, maintainAspectRatio: false, scales: { y: { beginAtZero: function() { j++; console.log('why this scale running this many times : ', j) return true } } } } }); <canvas id="myChart" width="200" height="200"></canvas> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js" integrity="sha512-asxKqQghC1oBShyhiBwA+YgotaSYKxGP1rcSYTDrB0U6DxwlJjU59B67U8+5/++uFjcuVM8Hh5cokLjZlhm3Vg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2"></script>Como leí en la documentación de ChartJs, borderColor debe ser Color y también su propiedad Scribtable, lo que significa que puede pasar una función con contexto y opciones como parámetros para tener una interfaz de usuario flexible
Por lo tanto, debe llamarse cada vez que cambien el contexto y las opciones.
Puede calcular su valor de color y pasarlo en lugar de pasar la función.
La función bordercolor se llama cada vez que su gráfico necesita dibujar un borde. Si asumió que se llamaría una vez, puede simplemente crear su propia función y darle a bordercolor el valor de retorno de esa función, no la función en sí.
No sé, por qué no reconoce el gradiente variable en jsfiddle
Si está tratando de crear un gradiente, ¿por qué la cantidad de veces que se llama a esta función importa de alguna manera? No creo que entiendas lo que preguntas.
Aquí está su ejemplo con un degradado, asumiendo que eso es lo que realmente necesita: JSFiddle
var ctx = document.getElementById('myChart').getContext('2d'); let width, height, gradient; function getGradient(ctx, chartArea) { const chartWidth = chartArea.right - chartArea.left; const chartHeight = chartArea.bottom - chartArea.top; if (gradient === null || width !== chartWidth || height !== chartHeight) { // Create the gradient because this is either the first render // or the size of the chart has changed width = chartWidth; height = chartHeight; gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top); gradient.addColorStop(0, "rgb(54, 162, 235)"); gradient.addColorStop(0.5, "rgb(255, 205, 86)"); gradient.addColorStop(1, "rgb(255, 99, 132)"); } return gradient; } var myChart = new Chart(ctx, { type: 'line', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: function(context) { const chart = context.chart; const {ctx, chartArea} = chart; if (!chartArea) { // This case happens on initial chart load return null; } return getGradient(ctx, chartArea); }, borderWidth: 1 }] }, options: { responsive: false, maintainAspectRatio: false, scales: { y: { beginAtZero: true, } }, } });Tomado de aquí.
Pude resolverlo, el problema con los gráficos predeterminados y los documentos chartjs, en general, es que no menciona que todas las opciones predeterminadas se ejecutan cada vez, y no sucede cuando define por separado las opciones de elementos en opciones, que podemos definir.
Por ejemplo, en un gráfico de líneas, podemos hacer opciones>elementos>línea>propiedades, esto solo se ejecutará después de que se hayan dibujado los gráficos, por lo que esto aumenta significativamente la eficiencia y reduce el procesamiento, también puede reducir las ejecuciones de funciones a la mitad al deshabilitar la animación en el gráfico (opciones> animación: falso)
Entonces, en mi caso, pude llevar la función de ejecución de 25 tiempos a la función de ejecución de 4 tiempos configurando correctamente las cosas mencionadas anteriormente.
Aquí está el js fiddle actualizado: https://jsfiddle.net/abhishek_soni/38mfez7g/57/
Además, aquí está el fragmento de código:
var ctx = document.getElementById('myChart').getContext('2d'); let i = 0, j = 0, k = 0; var myChart = new Chart(ctx, { type: 'line', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], }] }, options: { animation: false, // this reduces it by half as for all animations it's renders twice elements: { // this reduces it by number of options, as this is applied after the default options are run. line: { borderWidth: 1, borderColor: function() { ++i; console.log('why this bordercolor running this many times : ', i) return 'green' } }, }, responsive: function() { k++; console.log('why this option running this many times : ', k) return false }, maintainAspectRatio: false, scales: { y: { beginAtZero: function() { j++; console.log('why this scale running this many times : ', j) return true } } } } }); <canvas id="myChart" width="200" height="200"></canvas> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js" integrity="sha512-asxKqQghC1oBShyhiBwA+YgotaSYKxGP1rcSYTDrB0U6DxwlJjU59B67U8+5/++uFjcuVM8Hh5cokLjZlhm3Vg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2"></script>