J'aurais besoin d'ajouter un simple point/ligne verticale sur mon graphique bar
qui a une valeur X dynamique et 0 pour la valeur Y. Aperçu de ce dont j'ai besoin (le point rouge):
Où les valeurs vertes sont dynamiques.
Aperçu de mon état actuel:
Où 3,30 doit être la coordonnée X du point - [3,30, 0].
J'utilise Graphique vue pour les graphiques et j'ai essayé d'en créer un mixte avec les bar
et scatter
mais scatter
nécessite type: 'linear'
car c'est xAxis
qui ne correspond pas à mes besoins pour le graphique bar
.
J'ai donc essayé avec chartjs-plugin-annotation et c'est le type box
qui accepte les "coordonnées" mais le problème ici est que la valeur X
doit être une valeur fixe sur l'axe X (objet labels
). Si je mets pour l'axe X [3,0] cela fonctionnera, mais s'il y a un nombre décimal, comme [3,5, 0], cela ne fonctionnera pas.
// data
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
min: 0,
max: 1,
stepSize: 0.1
}
}]
}
}
// computed
labels: [1, 2, 3, 4, 5, 6], // fixed value, there are always 6 bars
datasets: [
{
label: 'Values',
backgroundColor: '#f89098',
data: this.tableInputValues // array of decimal values
}
]
Donc, ma question est de savoir comment placer un point "simple", ou une ligne verticale, sur un graphique à barres Chart.js où le point a une valeur dynamique pour l'axe X -> [dynamic valeur, 0].
Pour info - il s'agit de valeur attendue
Pour autant que je comprends Vue Le graphique fonctionne à l'aide de canvas (comme vu sur Page de démonstration ).
Donc, ma suggestion ici est de récupérer le nœud de canevas représentant le graphique dans votre DOM et d'écrire dynamiquement le point souhaité. Par exemple:
var c = document.getElementById("bar-chart"); //hereby assuming canvas named "bar-chart"
var ctx = c.getContext("2d");
ctx.fillStyle = "#ff0000"; //red color for the dot
ctx.beginPath();
let yPosition = c.height - 5; //fixed y position
let xPosition = 35; //that's the dynamic expected value
ctx.arc(xPosition, yPosition, 2.5, 0, 2 * Math.PI);
ctx.fill();
Ici vous trouverez une démo montrant comment y parvenir en utilisant Vue. Dans ce scénario, vous devez encapsuler le code pour dessiner un point sur le canevas dans un crochet afterDraw
. Ce crochet doit être attaché au composant graphique en tant que plugin, donc comme ceci:
...
mounted () {
//adding the plugin to draw the red dot
this.addPlugin({
id: 'chart-plugin',
afterDraw: function (chart) {
var c = chart.canvas;
var ctx = c.getContext("2d");
ctx.fillStyle = "#ff0000";
ctx.beginPath();
let xPosition = 742; //x positioning to be calculated according to your needs
let yPosition = c.height - 28;
ctx.arc(xPosition, yPosition, 3, 0, 2 * Math.PI);
ctx.fill();
}
});
//actual chart rendering
this.renderChart({
...
});
}
...
Par souci d'exhaustivité, ici vous trouverez la liste de tous les hooks disponibles de l'API du plugin Chart.js.
Ceci est ma solution pour votre problème https://jsfiddle.net/huynhsamha/e54djwxp/
Et c'est une capture d'écran pour le résultat
Dans ma solution, j'utilise type="line"
et les deux axes x et y avec type="linear"
. J'ajoute également la propriété options
à <chart>
pour utiliser options
dans ChartJS
<div id="vue">
<chart type="line" :data="data" :options="options"></chart>
</div>
options
configurera l'axe x et l'axe y pour rendre les points de données et la valeur attendue:
options: {
scales: {
xAxes: [{
type: 'linear',
ticks: {
min: 1,
max: 6,
stepSize: 1
}
}],
yAxes: [{
type: 'linear',
ticks: {
min: 0,
max: 1,
stepSize: 0.1
}
}]
}
}
Et le data
aura 2 datasets
. Le premier est les points de données, utilisez le type line
et le second est la valeur attendue qui utilise le type bubble
.
data: {
datasets: [{
label: 'Frequency Data',
data: dataPoints.map(({ val, freq }) => ({
x: val,
y: freq
})),
backgroundColor: 'rgba(72, 202, 59, 0.4)',
borderColor: 'rgba(72, 202, 59, 1)'
}, {
label: 'Expected Value',
type: 'bubble',
data: [{
x: expectedValue,
y: 0,
r: 8 // radius
}],
backgroundColor: 'rgba(255, 68, 0, 0.4)',
borderColor: 'rgba(255, 68, 0, 1)'
}]
},
Dans datasets
, nous avons dataPoints
et expectedValue
, il sera récupéré depuis l'API pour obtenir vos points de données. Je simule également l'API simple pour les points de données:
// simulate the API to get data points
const retrieveData = () => [
{ val: 1, freq: 0.15 },
{ val: 2, freq: 0.25 },
{ val: 3, freq: 0.3 },
{ val: 4, freq: 0.2 },
{ val: 5, freq: 0.1 },
{ val: 6, freq: 0.45 }
]
// fetch your data here, return array of JSON { val, freg }
const dataPoints = retrieveData() || [];
// calculate expected value = sum( val * freq ) each i in dataPoints
const expectedValue = dataPoints.reduce((cur, { val, freq }) => cur + val * freq, 0).toFixed(4);
Vous pouvez exécuter l'extrait de code ou exécuter sur le violon https://jsfiddle.net/huynhsamha/e54djwxp/92/
<script async src="//jsfiddle.net/huynhsamha/e54djwxp/92/embed/js,html,css,result/dark/"></script>