Correction d'une erreur de sérialisation JSON dans les graphiques en secteurs WeChat Mini Program

Lors du développement d'une page de graphiques en secteurs dans une application WeChat Mini Program nécessitant l'impression simultanée de plusieurs visualisations, une erreur critique de sérialisation JSON survient lors de la gestion des enstances ECharts.

Diagnostic de l'erreru

L'erreur suivante apparaît lors de l'exécution :

VM6541:1 thirdScriptError
Converting circular structure to JSON; at setTimeout callback
TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at e.exports.send (asdebug.js:1:1950)
    at Object.n [as publish] (asdebug.js:1:26961)
    at WAService.js:1:423146

Ce problème est causé par la tentative de sérialisation d'objets circulaires lors de l'utilisation de setData() avec des références ECharts directement stockées dans le modèle de données.

Solution technique

L'approche initiale consistait à stocker les instances de graphiques dans le modèle de données via des fonctions d'initialisation imbriquées, créant des références circulaires. Voici la méthode corrigée :

1. Structure WXML optimisée

<view class="graphique-container">
  <ec-canvas id="source-chart" canvas-id="source-canvas" 
             bind:init="gestionnaireInitSource"/>
</view>

<view class="separateur"/>

<view class="graphique-container">
  <ec-canvas id="categorie-chart" canvas-id="categorie-canvas" 
             bind:init="gestionnaireInitCategorie"/>
</view>

2. Implémentation JavaScript révisée

import * as echarts from '../../lib/echarts';
import configOptions from '../../config/graphique-options';

Page({
  data: {
    optionsSource: {},
    optionsCategorie: {}
  },

  onLoad() {
    wx.showLoading({ title: 'Chargement...' });
    this.initialiserGraphiques();
  },

  initialiserGraphiques() {
    setTimeout(() => {
      this.mettreAJourGraphique(
        this.grapheSource, 
        'Sources de données', 
        'Rapport mensuel',
        [
          { value: 9432, name: 'Web scraping' },
          { value: 24123, name: 'Import historique' },
          { value: 14242, name: 'Systèmes externes' }
        ]
      );
      
      this.mettreAJourGraphique(
        this.grapheCategorie,
        'Classification',
        'Trimestre en cours',
        [
          { value: 19432, name: 'Printemps' },
          { value: 24123, name: 'Été' },
          { value: 14242, name: 'Automne' },
          { value: 24242, name: 'Hiver' }
        ]
      );
      wx.hideLoading();
    }, 200);
  },

  initialiserInstance(canvas, width, height) {
    const instance = echarts.init(canvas, null, { width, height });
    canvas.setChart(instance);
    instance.setOption(configOptions);
    return instance;
  },

  gestionnaireInitSource(event) {
    this.grapheSource = this.initialiserInstance(
      event.detail.canvas, 
      event.detail.width, 
      event.detail.height
    );
  },

  gestionnaireInitCategorie(event) {
    this.grapheCategorie = this.initialiserInstance(
      event.detail.canvas, 
      event.detail.width, 
      event.detail.height
    );
  },

  mettreAJourGraphique(instance, titre, serie, donnees) {
    instance.setOption({
      title: { text: titre },
      series: [{ name: serie, data: donnees }]
    });
  }
});

La solution consiste à :

  1. Éviter le stockage direct des instances ECharts dans data
  2. Utiliser des gestionnaires d'événements bind:init pour capturer les références
  3. Conserver les instances dans des propriétés de classe plutôt que dans le modèle de données
  4. Supprimer les fermetures JavaScript créant des dépendances circulaires

Cette approche prévient la sérialisation accidentelle d'objets complexes lors des opérations internes de WeChat Mini Program.

Étiquettes: wechat-mini-program ECharts JSON-Circular-Reference JavaScript-Optimization Canvas-Rendering

Publié le 9 octobre à 09h37