Я создал опрос в режиме реального времени с помощью Chart.js и хочу, чтобы пользователь мог выбрать свою опцию, установив флажок слева от метки оси Y. У меня проблемы с выяснением, как сделать это правильно с Chart.js
Моей первой попыткой было поместить поле ввода за пределы холста, но оно очень ненадежно с опциями динамического опроса по мере их роста. Это довольно плохо, потому что высота гистограммы будет варьироваться в зависимости от количества доступных вариантов, поэтому поля ввода становятся беспорядочными, поскольку отображаемые параметры являются динамическими.
Вот изображение того, чего я в конечном итоге пытаюсь достичь на внешнем интерфейсе. Если пользователь выбирает поле, опрос увеличивается, чтобы отразить выбор, выбранный пользователем.

Ниже приведен мой код, в котором я сейчас застрял. Я застрял, пытаясь понять это в течение достаточно долгого времени. Любая помощь будет принята с благодарностью!
import { Component, OnInit } from '@angular/core';
// import { Chart } from 'chart.js';
import * as Ably from 'ably';
import * as Chart from 'chart.js';
import { AngularFirestore } from '@angular/fire/firestore';
import { Observable, Subject } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { FirebaseService } from '../services/firebase.service';
@Component({
selector: 'app-vote-chart',
templateUrl: './vote-chart.component.html',
styleUrls: ['./vote-chart.component.scss']
})
export class VoteChartComponent implements OnInit {
// Attributes
ably: any
receiveChanel: any
chart: any
users: any
polls:any = [];
poll:any;
votes:any = [];
labels:any = [];
poll_type:string = "";
constructor(db: AngularFirestore, private firebaseService: FirebaseService) {}
ngOnInit() {
this.firebaseService.getPoll("key").subscribe(res => {
const poll_data:any = res.payload.data();
this.poll = {
id: res.payload.id,
helper_text: poll_data.helper_text,
poll_type: poll_data.poll_type,
scoring_type: poll_data.scoring_type,
user: poll_data.user.id,
choices: []
};
this.poll_type = this.poll.poll_type == 2 ? "Pick One" : "Pick Two";
this.firebaseService.getChoices('key').subscribe(res => {
res.forEach((choice) => {
const choice_data:any = choice.payload.doc.data()
this.poll.choices.push({
id: choice.payload.doc.id,
text: choice_data.text,
votes: choice_data.votes
});
this.votes.push(choice_data.votes);
this.labels.push(choice_data.text);
});
console.log("Poll updated!", this.poll);
});
});
this.ably = new Ably.Realtime("key")
// Attach to channel
this.receiveChanel = this.ably.channels.get('vote-channel12')
// Ably subscription
this.receiveChanel.subscribe("update", (message: any) => {
var canvas = <HTMLCanvasElement> document.getElementById("chartjs-2")
var ctx = canvas.getContext("2d");
this.chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: this.labels,
datasets: [{
label: this.poll_type,
data: this.votes,
fill: false,
backgroundColor: [
"rgba(255, 99, 132, 0.2)",
"rgba(255, 159, 64, 0.2)",
"rgba(255, 205, 86, 0.2)",
"rgba(75, 192, 192, 0.2)",
"rgba(54, 162, 235, 0.2)",
"rgba(153, 102, 255, 0.2)",
"rgba(201, 203, 207, 0.2)"
],
borderColor: [
"rgb(255, 99, 132)",
"rgb(255, 159, 64)",
"rgb(255, 205, 86)",
"rgb(75, 192, 192)",
"rgb(54, 162, 235)",
"rgb(153, 102, 255)",
"rgb(201, 203, 207)"
],
borderWidth: 1
}]
},
options: {
events: ["touchend", "click", "mouseout"],
onClick: function(e) {
console.log("clicked!", e);
},
tooltips: {
enabled: true
},
title: {
display: true,
text: this.poll_type,
fontSize: 14,
fontColor: '#666'
},
legend: {
display: false
},
maintainAspectRatio: true,
responsive: true,
scales: {
xAxes: [{
ticks: {
beginAtZero: true,
precision: 0
}
}]
}
}
})
console.log("Poll", this.poll);
});
}
}
Шаблон кода, встроенный стиль для упрощения просмотра
<div id="chart_and_labels_container" style="min-width:620px !important;">
<div style="float:left; line-height: 175px; display: inline-grid; padding-top: 55px; margin: 0;">
<input type="checkbox" (click)="vote(1)" style="width:57px; height: 30px;"/>
<input type="checkbox" (click)="vote(-1)" style="width:57px; margin-top: 10px; height: 30px;"/>
<input type="checkbox" (click)="vote(-1)" style="width:57px; margin-top: 10px; height: 30px;"/>
</div>
<div id="canvasDiv" style="width: 425px; float:left;">
<canvas id="chartjs-2" ></canvas>
</div>
</div>
** ОБНОВЛЕНИЕ **
Если невозможно получить поля ввода на холсте, может кто-нибудь дать совет о том, как лучше всего убедиться, что поля ввода надежно совпадают с динамическими вариантами? Т.е. размер текста для надписей различен для 2 вариантов по сравнению с 5 вариантами. Как правильно и надежно выстроить поля ввода вне холста?