ChartJS 如何根据下拉过滤器动态呈现新的图表列表?

6xfqseft  于 2023-08-05  发布在  Chart.js
关注(0)|答案(1)|浏览(176)

我没有尝试刷新刀片式服务器上的现有图表。这里的情况下,每个模块都有一个问题,选项和答案(由用户选择的选项)的列表。我有一个下拉菜单来按模块筛选问题。
我设法在加载时为第一个模块动态生成图表,但当我更改为模块2时,chartData会更新并通过emit传递回脚本,但我无法更新刀片。我得到的错误是,Uncaught(in promise)TypeError:无法从const ctx = document.getElementById(canvasId).getContext('2d')读取4:2072:66的null(阅读'getContext')的属性;.
我也提到了这个Destroy chart.js bar graph to redraw other graph in same ,任何帮助是赞赏。
Livewire组件

  1. public function mount()
  2. {
  3. $this->modules = $this->session->course->modules->where('status', 'PUBLISHED');
  4. $this->selectedModule = $this->modules->first()->id;
  5. $this->GetQuestions();
  6. $this->preparePieChartData();
  7. }
  8. public function preparePieChartData()
  9. {
  10. $singleChoiceQuestions = $this->questions->where('type', 'single_choice');
  11. $data = [];
  12. foreach ($singleChoiceQuestions as $question) {
  13. if ($question->answers->count() > 0) {
  14. $options = $question->options;
  15. $questionData = [
  16. 'question' => $question->question_text,
  17. 'options' => [],
  18. ];
  19. foreach ($options as $option) {
  20. $count = $question->answers
  21. ->where('option_uuid', $option->uuid)
  22. ->where('session_id', $this->session->id)
  23. ->count();
  24. $questionData['options'][] = [
  25. 'option' => $option->option_text,
  26. 'count' => $count,
  27. ];
  28. }
  29. $data[] = $questionData;
  30. }
  31. }
  32. $this->chartData = $data;
  33. $this->emitSelf('chartDataUpdated', $data);
  34. }
  35. public function updatedSelectedModule()
  36. {
  37. $this->GetQuestions();
  38. $this->preparePieChartData();
  39. }

字符串
在刀刃上

  1. <select class="form-control-sm form-control" wire:model="selectedModule">
  2. @foreach($modules as $module)
  3. <option value="{{ $module->id }}">{{ $module->title }}</option>
  4. @endforeach
  5. </select>
  6. @foreach($questions as $question)
  7. if ($question->type == 'single_choice')
  8. <canvas id="pieChart{{ $loop->index }}" style="max-height: 300px; display: block;"></canvas>
  9. @endif
  10. @endforeach


在刀锋剧本的结尾

  1. <script>
  2. document.addEventListener('livewire:load', function () {
  3. const chartInstances = [];
  4. function GenerateCharts(chartData) {
  5. console.log('drawing charts...');
  6. chartData.forEach((chart, index) => {
  7. console.log(index);
  8. console.log(chart);
  9. const config = {
  10. type: 'pie',
  11. data: {
  12. labels: chart.options.map(option => option.option),
  13. datasets: [{
  14. label: 'Total',
  15. data: chart.options.map(option => option.count),
  16. }]
  17. },
  18. options: {
  19. plugins: {}
  20. },
  21. }
  22. const canvasId = `pieChart${index}`;
  23. if (chartInstances[canvasId]) {
  24. chartInstances[canvasId].destroy();
  25. delete chartInstances[canvasId];
  26. }
  27. const ctx = document.getElementById(canvasId).getContext('2d');
  28. chartInstances[canvasId] = new Chart(ctx, config);
  29. });
  30. }
  31. GenerateCharts(@js($chartData));
  32. @this.on('chartDataUpdated', (data) => {
  33. GenerateCharts(data);
  34. });
  35. });
  36. </script>

wwwo4jvm

wwwo4jvm1#

您可以使用事件重新调用脚本。例如,您可以使用updated方法捕获哪个字段已更新:

  1. public function updated($field, $value)
  2. {
  3. // Validate which field should trigger a chart update. If all updates should, no if statement is needed.
  4. if ($field === 'questions') {
  5. $this->dispatchBrowserEvent('update-chart');
  6. }
  7. }

字符串
然后在前端,你可以抓住它:

  1. window.addEventListener('update-chart', () => {
  2. // Tear down current chart and initialize new chart
  3. });

展开查看全部

相关问题