476

Configurer des graphiques par Plotly

Cet article explique comment programmer la configuration d'un graphique linéaire et l'édition d'un graphique à barres réalisés avec la librairie fournie par Plotly.

Plotly

IMPORTANT : La disposition et le style d'une interface sont à la discrétion du programmeur. Aucun modèle graphique n'est imposé. Les programmes en exemple utilisent les icônes de Font Awesome.

Configuration d'un graphique linéraire

 X
 Y
 lines  markers
   

Utilisez le sélecteur   pour éditer les données et les paramètres de configuration d'une ligne du graphe. La position de la ligne sélectionnée et le nombre total de lignes sont affichés à droite des boutons.

Entrez une séries de nombres séparés par des espaces pour l'axe des X et pour l'axe des Y.

Tapez le titre de la ligne dans le champ de saisie suivant.

Cliquez dans le champ de saisie d'une couleur. Choisissez une couleur. Appuyez sur Entrée ou cliquez en dehors du sélecteur pour valider la couleur choisie. Le tracé et les marqueurs de la ligne changent de couleur. Entrez directement une valeur, e.g. #C80.

Cochez l'option pour cacher la ligne.

Choisissez un type de tracé avec des lines lignes, des markers marqueurs ou des lines+markers lignes avec des marqueurs.

Spécifiez la largeur des lines lignes et des markersmarqueurs.

Sélectionnez un type de ligne solid solide, solid en pointillé ou dashdot alterné.

Cliquez sur le bouton plus pour ajouter une ligne.

Cliquez sur le bouton moins pour supprimer la ligne sélectionnée.

Utilisez les flèches   pour réordonner la ligne sélectionnée.

Tapez le titre du graphique dans le champ de saisie suivant.

Cochez l'option pour afficher la légende à droite du graphique.

Spécifiez le delta entre chaque marque sur l'axe des X et l'axe des Y.

Cochez les options et pour afficher les barres verticales et horizontales de la grille.

NOTE : Les graphiques par Plotly ont beaucoup d'options. Ajouter des inspecteurs pour éditer plus d'options et montrer le résultat interactivement prend quelques minutes.

Code
  1. <?php $title='Plotly'; ?>
  2. <?php $name1='Markers'; ?>
  3. <?php $mode1='markers'; ?>
  4. <?php $color1='#8C0C3C'; ?>
  5. <?php $x1=array(1, 2, 3, 4); ?>
  6. <?php $y1=array(10, 15, 13, 17); ?>
  7. <?php $name2='Lines'; ?>
  8. <?php $mode2='lines'; ?>
  9. <?php $color2='#F7BD00'; ?>
  10. <?php $x2=array(1, 2, 3, 4); ?>
  11. <?php $y2=array(16, 5, 11, 9); ?>
  12. <?php $name3='Markers • Lines'; ?>
  13. <?php $mode3='lines+markers'; ?>
  14. <?php $color3='#C10037'; ?>
  15. <?php $x3=array(1, 2, 3, 4); ?>
  16. <?php $y3=array(12, 9, 15, 12); ?>

Définit le titre du graphique, la légende, le mode, la couleur et les données des 3 lignes du graphique.

  1. <?php head('javascript', 'jquery.minicolors'); ?>
  2. <?php head('stylesheet', 'jquery.minicolors', 'screen'); ?>

Ajoute les balises <script src="/js/jquery.minicolors.js"/> et <link rel="stylesheet" href="/css/jquery.minicolors.css" media="screen"/> à la section <head> du document HTML pour charger le code et la feuille de style de MiniColors en jQuery. head est une fonction d'iZend. Adaptez le code à votre environnement de développement.

  1. <?php head('javascript', 'https://cdn.plot.ly/plotly-latest.min.js'); ?>

Charge le code de la librairie Plotly.

  1. <?php $id=uniqid('id'); ?>

Définit l'identifiant de la <div> qui encadre le HTML du programme.

  1. i.btn_plotly {width:20px;height:16px;display:inline-block;line-height:16px;background:transparent url(/objectivejs/tests/images/plotly.png) no-repeat;vertical-align:middle;text-indent:-9999px;}
  2. i.btn_lines {background-position:0 0;}
  3. i.btn_markers {background-position:-20px 0;}
  4. i.btn_lines_markers {background-position:-40px 0;}
  5. i.btn_solid {background-position:-60px 0;}
  6. i.btn_dot {background-position:-80px 0;}
  7. i.btn_dashdot {background-position:-100px 0;}

Configure l'apparence des boutons spécialement créés pour interfacer Plotly.

Plotly

  1. #<?php echo $id; ?>_line_width, #<?php echo $id; ?>_marker_size {
  2.     width: 3em;
  3. }
  4. #<?php echo $id; ?>_xaxis_dtick, #<?php echo $id; ?>_yaxis_dtick {
  5.     width: 3em;
  6. }
  7. #<?php echo $id; ?>_xaxis_dtick::-webkit-inner-spin-button,
  8. #<?php echo $id; ?>_xaxis_dtick::-webkit-outer-spin-button,
  9. #<?php echo $id; ?>_yaxis_dtick::-webkit-inner-spin-button,
  10. #<?php echo $id; ?>_yaxis_dtick::-webkit-outer-spin-button {
  11.     -webkit-appearance: none;
  12.     margin: 0;
  13. }
  14. #<?php echo $id; ?>_xaxis_dtick,
  15. #<?php echo $id; ?>_yaxis_dtick {
  16.     -moz-appearance: textfield;
  17. }

Configure la largeur des champs de saisie de la largeur d'une ligne et de la largeur d'un marqueur, du delta entre chaque marque sur l'axe des X et l'axe des Y. Montre comment cacher les flèches affichées par un <input type="number">.

  1. <div id="<?php echo $id; ?>" class="noprint">
  2. <div class="test_display"></div>
  3. <div class="ojs">
  4. <div>
  5. <span><button id="<?php echo $id; ?>_prev" type="submit" class="tiny round"><i class="fas fa-caret-left"></i></button></span>
  6. <span><button id="<?php echo $id; ?>_next" type="submit" class="tiny round"><i class="fas fa-caret-right"></i></button></span>
  7. <span><output id="<?php echo $id; ?>_index"></output></span>
  8. </div>
  9. <div>
  10. <span><input id="<?php echo $id; ?>_x" type="text" size="30" spellcheck="false" title="X" placeholder="1 2 3 4 ..."/>&nbsp;<b class="small">X</b></span>
  11. </div>
  12. <div>
  13. <span><input id="<?php echo $id; ?>_y" type="text" size="30" spellcheck="false" title="Y" placeholder="-5 2.5 10 5 ..."/>&nbsp;<b class="small">Y</b></span>
  14. </div>
  15. <div>
  16. <span><input id="<?php echo $id; ?>_name" type="text" size="20" spellcheck="false"/></span>
  17. <span id="<?php echo $id; ?>_line_color"></span>
  18. <span class="nowrap"><input id="<?php echo $id; ?>_hidden" type="checkbox"/><i class="fas fa-minus-circle red"></i></span>
  19. </div>
  20. <div>
  21. <span id="<?php echo $id; ?>_mode">
  22. <span><input type="radio" id="<?php echo $id; ?>_mode_lines" name="<?php echo $id; ?>_mode" value="lines" checked><label for="<?php echo $id; ?>_mode_lines"><i class="btn_plotly btn_lines">lines</i></label></span>
  23. <span><input type="radio" id="<?php echo $id; ?>_mode_markers" name="<?php echo $id; ?>_mode" value="markers"><label for="<?php echo $id; ?>_mode_markers"><i class="btn_plotly btn_markers">markers</i></label></span>
  24. <span><input type="radio" id="<?php echo $id; ?>_mode_lines_markers" name="<?php echo $id; ?>_mode" value="lines+markers"><label for="<?php echo $id; ?>_mode_lines_markers"><i class="btn_plotly btn_lines_markers">lines+markers</i></label></span>
  25. </span>
  26. <span><input id="<?php echo $id; ?>_line_width" type="number" min="1" max="10" step="1"/>&nbsp;<i class="btn_plotly btn_lines">lines</i></span>
  27. <span><input id="<?php echo $id; ?>_marker_size" type="number" min="1" max="60" step="1"/>&nbsp;<i class="btn_plotly btn_markers">markers</i></span>
  28. </div>
  29. <div>
  30. <span id="<?php echo $id; ?>_line_dash">
  31. <span><input type="radio" id="<?php echo $id; ?>_line_dash_solid" name="<?php echo $id; ?>_line_dash" value="solid"><label for="<?php echo $id; ?>_line_dash_solid"><i class="btn_plotly btn_solid">solid</i></label></span>
  32. <span><input type="radio" id="<?php echo $id; ?>_line_dash_dot" name="<?php echo $id; ?>_line_dash" value="dot"><label for="<?php echo $id; ?>_line_dash_dot"><i class="btn_plotly btn_dot">dot</i></label></span>
  33. <span><input type="radio" id="<?php echo $id; ?>_line_dash_dashdot" name="<?php echo $id; ?>_line_dash" value="dashdot"><label for="<?php echo $id; ?>_line_dash_dashdot"><i class="btn_plotly btn_dashdot">dashdot</i></label></span>
  34. </span>
  35. </div>
  36. <div>
  37. <span><button id="<?php echo $id; ?>_add" type="submit" class="tiny"><i class="fas fa-sm fa-plus"></i></button></span>
  38. <span><button id="<?php echo $id; ?>_remove" type="submit" class="tiny"><i class="fas fa-sm fa-minus"></i></button></span>
  39. <span><button id="<?php echo $id; ?>_shift" type="submit" class="tiny"><i class="fas fa-sm fa-arrow-up"></i></button></span>
  40. <span><button id="<?php echo $id; ?>_unshift" type="submit" class="tiny"><i class="fas fa-sm fa-arrow-down"></i></button></span>
  41. </div>
  42. <div>
  43. <span><input id="<?php echo $id; ?>_title" type="text" size="30"/></span>
  44. <span class="nowrap"><input id="<?php echo $id; ?>_legend" type="checkbox"/><i class="fas fa-list fa-xs"></i></span>
  45. </div>
  46. <div>
  47. <span><input id="<?php echo $id; ?>_xaxis_dtick" type="number"/>&nbsp;<i class="fas fa-arrows-alt-h fa-xs"></i></span>
  48. <span><input id="<?php echo $id; ?>_yaxis_dtick" type="number"/>&nbsp;<i class="fas fa-arrows-alt-v fa-xs"></i></span>
  49. <span class="nowrap"><input id="<?php echo $id; ?>_xaxis_grid" type="checkbox"/><i class="fas fa-grip-lines-vertical fa-xs"></i></span>
  50. <span class="nowrap"><input id="<?php echo $id; ?>_yaxis_grid" type="checkbox"/><i class="fas fa-grip-lines fa-xs"></i></span>
  51. </div>
  52. </div>
  53. </div>

Crée les widgets de l'interface.

  1. <?php head('javascript', '/objectivejs/Objective.js'); ?>
  2. <?php head('javascript', '/objectivejs/Validator.js'); ?>
  3. <?php head('javascript', '/objectivejs/Responder.js'); ?>
  4. <?php head('javascript', '/objectivejs/View.js'); ?>
  5. <?php head('javascript', '/objectivejs/Inspector.js'); ?>
  6. <?php head('javascript', '/objectivejs/BooleanInspector.js'); ?>
  7. <?php head('javascript', '/objectivejs/StringInspector.js'); ?>
  8. <?php head('javascript', '/objectivejs/NumberInspector.js'); ?>
  9. <?php head('javascript', '/objectivejs/RangeInspector.js'); ?>
  10. <?php head('javascript', '/objectivejs/OptionInspector.js'); ?>
  11. <?php head('javascript', '/objectivejs/ColorInspector.js'); ?>
  12. <?php head('javascript', '/objectivejs/SequenceInspector.js'); ?>
  13. <?php head('javascript', '/objectivejs/SetOfInspector.js'); ?>

Inclut le code de toutes les classes nécessaires. RAPPEL : La fonction head de la librairie iZend ajoute une balise telle que <script src="/objectivejs/Objective.js"></script> à la section <head> du document HTML. Adaptez le code à votre environnement de développement.

  1. function Tester(display, inspector) {
  2.     Responder.call(this);
  3.  
  4.     this._display = display;
  5.  
  6.     inspector.addNextResponder(this);
  7.  
  8.     this._inspector = inspector;
  9.  
  10.     this._plotly = null;
  11. }
  12.  
  13. Tester.prototype = Object.create(Responder.prototype);
  14.  
  15. Object.defineProperty(Tester.prototype, 'constructor', { value: Tester, enumerable: false, writable: true });
  16.  
  17. Tester.prototype.get = function() {
  18.     return this._inspector.get();
  19. }
  20.  
  21. Tester.prototype.set = function(value) {
  22.     if (!this._inspector.set(value))
  23.         return false;
  24.  
  25.     this.plot(this._inspector.get());
  26.  
  27.     return true;
  28. }
  29.  
  30. Tester.prototype.inspectorValueChanged = function(sender) {
  31.     if (sender === this._inspector)
  32.         this.plot(sender.get());
  33.  
  34.     return true;
  35. }
  36.  
  37. Tester.prototype.plot = function(value) {
  38.     const config = {
  39.         staticPlot: true,
  40.         responsive: true
  41.     };
  42.  
  43.     const layout = {
  44.         height: 360,
  45.         margin: { l: 20, r: 20, t: 50, b: 40 },
  46.         title: value.layout.title,
  47.         showlegend: value.layout.legend,
  48.         xaxis: {
  49.             dtick: value.layout.xaxisdtick,
  50.             showgrid: value.layout.xaxisgrid,
  51.             zeroline: false
  52.         },
  53.         yaxis: {
  54.             dtick: value.layout.yaxisdtick,
  55.             showgrid: value.layout.yaxisgrid,
  56.             zeroline: false
  57.         }
  58.     };
  59.  
  60.     const data = [];
  61.  
  62.     for (let v of value.data) {
  63.         const trace = {};
  64.  
  65.         trace.type = 'scatter';
  66.  
  67.         trace.name = v.name;
  68.  
  69.         trace.x = v.x.match(/-?\d+(\.\d+)?/g);
  70.         trace.y = v.y.match(/-?\d+(\.\d+)?/g);
  71.  
  72.         trace.mode = v.mode;
  73.         trace.visible = !v.hidden;
  74.  
  75.         trace.line = {
  76.             color: v.linecolor,
  77.             width: v.linewidth,
  78.             dash: v.linedash
  79.         };
  80.  
  81.         trace.marker = {
  82.             color: v.linecolor,
  83.             size: v.markersize
  84.         };
  85.  
  86.         data.push(trace);
  87.     }
  88.  
  89.     if (this._plotly === null)
  90.         this._plotly = Plotly.newPlot(this._display, data, layout, config);
  91.     else
  92.         Plotly.react(this._display, data, layout);
  93.  
  94.     return this;
  95. }
  1. const container = document.querySelector('#<?php echo $id; ?>');
  2.  
  3. const linecolor = new ColorInspector();
  4.  
  5. linecolor.createManagedWidget(document.getElementById('<?php echo $id; ?>_line_color'));
  6.  
  7. const linewidth = new NumberInspector(3, { min: 1, max: 10 });
  8.  
  9. linewidth.setManagedWidget(document.getElementById('<?php echo $id; ?>_line_width')).resetWidget();
  10.  
  11. const markersize = new NumberInspector(3, { min: 1, max: 60 });
  12.  
  13. markersize.setManagedWidget(document.getElementById('<?php echo $id; ?>_marker_size')).resetWidget();
  14.  
  15. const mode = new OptionInspector('lines', { tags: ['lines', 'markers', 'lines+markers'] });
  16.  
  17. mode.setManagedWidget(document.getElementById('<?php echo $id; ?>_mode')).resetWidget();
  18.  
  19. const linedash = new OptionInspector('solid', { tags: ['solid', 'dot', 'dashdot'] });
  20.  
  21. linedash.setManagedWidget(document.getElementById('<?php echo $id; ?>_line_dash')).resetWidget();
  22.  
  23. const name = new StringInspector();
  24.  
  25. name.setManagedWidget(document.getElementById('<?php echo $id; ?>_name')).resetWidget();
  26.  
  27. const x = new StringInspector();
  28.  
  29. x.setManagedWidget(document.getElementById('<?php echo $id; ?>_x')).resetWidget();
  30.  
  31. const y = new StringInspector();
  32.  
  33. y.setManagedWidget(document.getElementById('<?php echo $id; ?>_y')).resetWidget();
  34.  
  35. const hidden = new BooleanInspector(false);
  36.  
  37. hidden.setManagedWidget(document.getElementById('<?php echo $id; ?>_hidden')).resetWidget();
  38.  
  39. const trace = new SequenceInspector({
  40.     x: x,
  41.     y: y,
  42.     name: name,
  43.     mode: mode,
  44.     linedash: linedash,
  45.     linecolor: linecolor,
  46.     linewidth: linewidth,
  47.     markersize: markersize,
  48.     hidden: hidden
  49. });
  50.  
  51. const trace0 = {
  52.     x: '',
  53.     y: '',
  54.     name: '',
  55.     mode: 'lines',
  56.     linedash: 'solid',
  57.     linecolor: '#333',
  58.     linewidth: 3,
  59.     markersize: 10,
  60.     hidden: false
  61. };
  62.  
  63. const data = new SetOfInspector(trace, { min: 1, defaultItem: trace0 });
  64.  
  65. data.setPreviousWidget(document.getElementById('<?php echo $id; ?>_prev'));
  66. data.setNextWidget(document.getElementById('<?php echo $id; ?>_next'));
  67.  
  68. data.setIndexWidget(document.getElementById('<?php echo $id; ?>_index'));
  69.  
  70. data.setAddWidget(document.getElementById('<?php echo $id; ?>_add'));
  71. data.setRemoveWidget(document.getElementById('<?php echo $id; ?>_remove'));
  72.  
  73. data.setShiftWidget(document.getElementById('<?php echo $id; ?>_shift'));
  74. data.setUnshiftWidget(document.getElementById('<?php echo $id; ?>_unshift'));
  75.  
  76. const title = new StringInspector('<?php echo $title; ?>', { escapeHTML: false });
  77.  
  78. title.setManagedWidget(document.getElementById('<?php echo $id; ?>_title')).resetWidget();
  79.  
  80. const legend = new BooleanInspector(true);
  81.  
  82. legend.setManagedWidget(document.getElementById('<?php echo $id; ?>_legend')).resetWidget();
  83.  
  84. const xaxisdtick = new NumberInspector(0, { min: 0 });
  85.  
  86. xaxisdtick.setManagedWidget(document.getElementById('<?php echo $id; ?>_xaxis_dtick')).resetWidget();
  87.  
  88. const yaxisdtick = new NumberInspector(0, { min: 0 });
  89.  
  90. yaxisdtick.setManagedWidget(document.getElementById('<?php echo $id; ?>_yaxis_dtick')).resetWidget();
  91.  
  92. const xaxisgrid = new BooleanInspector(false);
  93.  
  94. xaxisgrid.setManagedWidget(document.getElementById('<?php echo $id; ?>_xaxis_grid')).resetWidget();
  95.  
  96. const yaxisgrid = new BooleanInspector(true);
  97.  
  98. yaxisgrid.setManagedWidget(document.getElementById('<?php echo $id; ?>_yaxis_grid')).resetWidget();
  99.  
  100. const layout = new SequenceInspector({
  101.     title: title,
  102.     legend: legend,
  103.     xaxisdtick: xaxisdtick,
  104.     yaxisdtick: yaxisdtick,
  105.     xaxisgrid: xaxisgrid,
  106.     yaxisgrid: yaxisgrid
  107. });
  108.  
  109. const inspector = new SequenceInspector({ data: data, layout: layout });
  110.  
  111. const line1 = {
  112.     x: '<?php echo implode(' ', $x1); ?>',
  113.     y: '<?php echo implode(' ', $y1); ?>',
  114.     name: '<?php echo $name1; ?>',
  115.     mode: '<?php echo $mode1; ?>',
  116.     linedash: 'solid',
  117.     linewidth: 3,
  118.     markersize: 20,
  119.     linecolor: '<?php echo $color1; ?>',
  120.     hidden: false
  121. };
  122. const line2 = {
  123.     x: '<?php echo implode(' ', $x2); ?>',
  124.     y: '<?php echo implode(' ', $y2); ?>',
  125.     name: '<?php echo $name2; ?>',
  126.     mode: '<?php echo $mode2; ?>',
  127.     linedash: 'solid',
  128.     linewidth: 5,
  129.     markersize: 10,
  130.     linecolor: '<?php echo $color2; ?>',
  131.     hidden: false
  132. };
  133. const line3 = {
  134.     x: '<?php echo implode(' ', $x3); ?>',
  135.     y: '<?php echo implode(' ', $y3); ?>',
  136.     name: '<?php echo $name3; ?>',
  137.     mode: '<?php echo $mode3; ?>',
  138.     linedash: 'dashdot',
  139.     linewidth: 3,
  140.     markersize: 10,
  141.     linecolor: '<?php echo $color3; ?>',
  142.     hidden: false
  143. };
  144.  
  145. const display = container.querySelector('.test_display');
  146.  
  147. const tester = new Tester(display, inspector);
  148.  
  149. tester.set({
  150.     data: [line1, line2, line3],
  151.     layout: {
  152.         title: '<?php echo $title; ?>',
  153.         legend: true,
  154.         xaxisdtick: 1,
  155.         xaxisgrid: false,
  156.         yaxisgrid: true
  157.     }
  158. });

Édition d'un graphique à barres

 X  Y

Changez le titre du graphique à Plotly & Objective.js. Remarquez que le caractère & n'est pas échappé. Cochez l'option pour afficher la légende du graphique.

Utilisez le sélecteur   pour éditer les données et la couleur d'une série de barres. Appuyez sur les flèches   pour déplacer la série de barres sélectionnée vers la gauche ou vers la droite.

Essayez de défaire et de refaire une modification. Cliquez sur le bouton de remise à zéro pour réinitialiser le graphique.

Rechargez la page. Les modifications sont enregistrées.

Code

Voir Architecture d'un éditeur.

Objective
  • Model
    • BarChartModel
  1. function BarChartModel(chartname) {
  2.     Model.call(this, chartname);
  3.  
  4.     this._value = {
  5.         data: null, layout: { title: '', legend: false }
  6.     };
  7. }
  8.  
  9. BarChartModel.prototype = Object.create(Model.prototype);
  10.  
  11. Object.defineProperty(BarChartModel.prototype, 'constructor', { value: BarChartModel, enumerable: false, writable: true });
  12.  
  13. BarChartModel.prototype.validateValue = function(prop, val) {
  14.     if (prop == 'data')
  15.         return val === null || Array.isArray(val);
  16.  
  17.     if (prop == 'layout') {
  18.         if (typeof val !== 'object')
  19.             return false;
  20.  
  21.         const { title, legend } = val;
  22.  
  23.         if (typeof title !== 'string')
  24.             return false;
  25.  
  26.         if (typeof legend !== 'boolean')
  27.             return false;
  28.  
  29.         return true;
  30.     }
  31.  
  32.     return true;
  33. };
Objective
  • Responder
    • View
      • BarChart
  1. function BarChart() {
  2.     View.call(this);
  3.  
  4.     this._data = null;
  5.     this._layout = null;
  6.  
  7.     this._plotly = null;
  8. }
  9.  
  10. BarChart.prototype = Object.create(View.prototype);
  11.  
  12. Object.defineProperty(BarChart.prototype, 'constructor', { value: BarChart, enumerable: false, writable: true });
  13.  
  14. BarChart.prototype._draw = function() {
  15.     const config = {
  16.         staticPlot: true,
  17.         responsive: true
  18.     };
  19.  
  20.     const layout = {
  21.         margin: { l: 30, r: 20, t: 50, b: 40 },
  22.         title: this._layout.title,
  23.         showlegend: this._layout.legend,
  24.         barmode: 'group',
  25.         xaxis: {
  26.             dtick: 1,
  27.             showgrid: false,
  28.             zeroline: false
  29.         },
  30.         yaxis: {
  31.             showgrid: true,
  32.             zeroline: true
  33.         }
  34.     };
  35.  
  36.     const data = [];
  37.  
  38.     for (let v of this._data || []) {
  39.         const trace = {};
  40.  
  41.         trace.type = 'bar';
  42.  
  43.         trace.name = '';
  44.  
  45.         trace.x = v.x.match(/-?\d+(\.\d+)?/g);
  46.         trace.y = v.y.match(/-?\d+(\.\d+)?/g);
  47.  
  48.         trace.marker = {
  49.             color: v.markercolor
  50.         };
  51.  
  52.         data.push(trace);
  53.     }
  54.  
  55.     if (this._plotly === null)
  56.         this._plotly = Plotly.newPlot(this._widget, data, layout, config);
  57.     else
  58.         Plotly.react(this._widget, data, layout);
  59.  
  60.     return this;
  61. };
  62.  
  63. BarChart.prototype.set = function(options) {
  64.     const {data, layout} = options;
  65.  
  66.     this._data = data;
  67.     this._layout = layout;
  68.  
  69.     if (this.interfaced())
  70.         this.resetWidget();
  71.  
  72.     return this;
  73. };
  74.  
  75. BarChart.prototype.setValue = function(prop, val) {
  76.     if (prop == 'data')
  77.         this.setData(val);
  78.     else if (prop == 'layout')
  79.         this.setLayout(val);
  80.  
  81.     return this;
  82. };
  83.  
  84. BarChart.prototype.setData = function(data) {
  85.     this._data = data;
  86.  
  87.     if (this.interfaced())
  88.         this.resetWidget();
  89.  
  90.     return this;
  91. };
  92.  
  93. BarChart.prototype.setLayout = function(layout) {
  94.     this._layout = layout;
  95.  
  96.     if (this.interfaced())
  97.         this.resetWidget();
  98.  
  99.     return this;
  100. };
  101.  
  102. BarChart.prototype.resetWidget = function() {
  103.     this._draw();
  104.  
  105.     return this;
  106. };
  107.  
  108. BarChart.prototype.createWidget = function() {
  109.     const graphdiv = '<div></div>';
  110.  
  111.     let template = document.createElement('template');
  112.  
  113.     template.innerHTML = graphdiv;
  114.  
  115.     let widget = template.content.children[0];
  116.  
  117.     this.setWidget(widget);
  118.  
  119.     return this;
  120. };
  121.  
  122. BarChart.prototype.destroyWidget = function() {
  123.     if (this._widget)
  124.         Plotly.purge(this._widget);
  125.  
  126.     View.prototype.destroyWidget.call(this);
  127.  
  128.     this._plotly = null;
  129.  
  130.     return this;
  131. };
  1. <?php $debug=false; ?>

Mettre $debug à true permet d'accéder dans la console du navigateur à tous les composants de l'interface. Si $debug vaut false, tout le code en JavaScript est protégé par une fonction de fermeture.

  1. <?php $title='Plotly'; ?>
  2. <?php
  3. $data=array(
  4.     array('#8C0C3C', array(1, 4, 9, 16)),
  5.     array('#F7BD00', array(6, -8, -4.5, 8)),
  6.     array('#F75431', array(-15, -3, 4.5, -8)),
  7.     array('#C10037', array(-1, 3, -3, -4))
  8. );
  9. ?>

Définit le titre, la couleur et les données de chaque barre du graphique initial. NOTE : Dans une application web, ces paramètres pourraient être extraits d'une base de données et passés à la vue par un contrôleur.

  1. <?php head('javascript', 'js.cookie.js'); ?>
  2. <?php head('javascript', 'jquery.minicolors'); ?>
  3. <?php head('stylesheet', 'jquery.minicolors', 'screen'); ?>

Ajoute la balise <script src="/js/js.cookie.js"/> à la section <head> du document HTML pour charger le module js-cookie utilisé par la classe ModelCookieDelegate. Ajoute les balises <script src="/js/jquery.minicolors.js"/> et <link rel="stylesheet" href="/css/jquery.minicolors.css" media="screen"/> à la section <head> du document HTML pour charger le code et la feuille de style de MiniColors en jQuery. head est une fonction d'iZend. Adaptez le code à votre environnement de développement.

  1. <?php head('javascript', 'https://cdn.plot.ly/plotly-latest.min.js'); ?>

Charge le code de la librairie Plotly.

  1. <?php $id=uniqid('id'); ?>

Définit l'identifiant de la <div> qui encadre l'affichage de l'éditeur et du graphique.

  1. <div id="<?php echo $id; ?>" class="noprint">
  2. <div class="ojs">
  3. <div>
  4. <div class="undo_panel" style="margin-right:20px">
  5. <button type="submit" class="ojs_button narrow" disabled><i class="fas fa-undo"></i></button>
  6. <button type="submit" class="ojs_button narrow" disabled><i class="fas fa-redo"></i></button>
  7. </div>
  8. <button id="<?php echo $id; ?>_reset" type="submit" class="ojs_button narrow"><i class="fas fa-chart-bar"></i></button>
  9. </div>
  10. <div>
  11. <span><input id="<?php echo $id; ?>_title" type="text" size="30"/></span>
  12. <span class="nowrap"><input id="<?php echo $id; ?>_legend" type="checkbox"/><i class="fas fa-list fa-xs"></i></span>
  13. </div>
  14. <div>
  15. <span><button id="<?php echo $id; ?>_prev" type="submit" class="ojs_button tiny round"><i class="fas fa-caret-left"></i></button></span>
  16. <span><button id="<?php echo $id; ?>_next" type="submit" class="ojs_button tiny round"><i class="fas fa-caret-right"></i></button></span>
  17. <span><output id="<?php echo $id; ?>_index"></output></span>
  18. </div>
  19. <div>
  20. <span><input id="<?php echo $id; ?>_x" type="text" size="20" spellcheck="false" title="X"/>&nbsp;<b class="small">X</b></span>
  21. <span><input id="<?php echo $id; ?>_y" type="text" size="20" spellcheck="false" title="Y"/>&nbsp;<b class="small">Y</b></span>
  22. <span id="<?php echo $id; ?>_marker_color"></span>
  23. </div>
  24. <div>
  25. <span><button id="<?php echo $id; ?>_insert" type="submit" class="ojs_button tiny"><i class="fas fa-sm fa-plus"></i></button></span>
  26. <span><button id="<?php echo $id; ?>_remove" type="submit" class="ojs_button tiny"><i class="fas fa-sm fa-minus"></i></button></span>
  27. <span><button id="<?php echo $id; ?>_shift" type="submit" class="ojs_button tiny"><i class="fas fa-sm fa-arrow-left"></i></button></span>
  28. <span><button id="<?php echo $id; ?>_unshift" type="submit" class="ojs_button tiny"><i class="fas fa-sm fa-arrow-right"></i></button></span>
  29. </div>
  30. </div>
  31. </div>

Crée les widgets de l'interface.

  1. <?php head('javascript', '/objectivejs/Objective.js'); ?>
  2. <?php head('javascript', '/objectivejs/Validator.js'); ?>
  3. <?php head('javascript', '/objectivejs/Responder.js'); ?>
  4. <?php head('javascript', '/objectivejs/View.js'); ?>
  5. <?php head('javascript', '/objectivejs/Inspector.js'); ?>
  6. <?php head('javascript', '/objectivejs/BooleanInspector.js'); ?>
  7. <?php head('javascript', '/objectivejs/StringInspector.js'); ?>
  8. <?php head('javascript', '/objectivejs/ColorInspector.js'); ?>
  9. <?php head('javascript', '/objectivejs/SequenceInspector.js'); ?>
  10. <?php head('javascript', '/objectivejs/SetOfInspector.js'); ?>
  11. <?php head('javascript', '/objectivejs/Model.js'); ?>
  12. <?php head('javascript', '/objectivejs/Undo.js'); ?>
  13. <?php head('javascript', '/objectivejs/Panel.js'); ?>
  14. <?php head('javascript', '/objectivejs/UndoPanel.js'); ?>
  15. <?php head('javascript', '/objectivejs/Editor.js'); ?>
  16. <?php head('javascript', '/objectivejs/ModelCookieDelegate.js'); ?>
  17. <?php head('javascript', '/objectivejs/tests/BarChartModel.js'); ?>
  18. <?php head('javascript', '/objectivejs/tests/BarChart.js'); ?>

Inclut le code de toutes les classes nécessaires. Inclut le code du délégué si le clip a un nom.

  1. <?php if (!$debug): ?>
  2. (function() {
  3. <?php endif; ?>

Isole tout le code en JavaScript dans une fonction de fermeture si $debug vaut false.

  1.     const model = new BarChartModel('barchart');

Crée le modèle de données à éditer.

  1.     const container = document.querySelector('#<?php echo $id; ?>');

Récupère la <div> qui encadre le HTML du programme.

  1.     const plotly = new BarChart();
  2.  
  3.     plotly.createManagedWidget(container);

Crée l'instance de BarChart qui va afficher le graphique avec Plotly. Crée la <div> pour Plotly.

  1.     const panel = new UndoPanel();
  2.  
  3.     panel.setManagedWidget(container.querySelector('.undo_panel')).resetWidget();
  4.  
  5.     const x = new StringInspector();
  6.  
  7.     x.setManagedWidget(document.getElementById('<?php echo $id; ?>_x')).resetWidget();
  8.  
  9.     const y = new StringInspector();
  10.  
  11.     y.setManagedWidget(document.getElementById('<?php echo $id; ?>_y')).resetWidget();
  12.  
  13.     const markercolor = new ColorInspector();
  14.  
  15.     markercolor.createManagedWidget(document.getElementById('<?php echo $id; ?>_marker_color'));
  16.  
  17.     const trace = new SequenceInspector({
  18.         x: x, y: y, markercolor: markercolor
  19.     });

Crée le panneau avec les boutons pour défaire et refaire une modification. Crée les inspecteurs pour les données de l'axe des X, les données de l'axe des Y et la couleur d'une série. Crée l'instance de SequenceInspector qui gère ces 3 inspecteurs.

  1.     const trace0 = {
  2.         x: '1 2 3 4', y: '0', markercolor: '#333'
  3.     };
  4.  
  5.     const dataInspector = new SetOfInspector(trace, { min: 1, max: 10, defaultItem: trace0 });

Crée l'instance de SetOfInspector qui gère la liste des séries avec un nombre d'éléments limité à 10 et une valeur initiale.

  1.     dataInspector.setPreviousWidget(document.getElementById('<?php echo $id; ?>_prev'));
  2.     dataInspector.setNextWidget(document.getElementById('<?php echo $id; ?>_next'));
  3.  
  4.     dataInspector.setIndexWidget(document.getElementById('<?php echo $id; ?>_index'));
  5.  
  6.     dataInspector.setInsertWidget(document.getElementById('<?php echo $id; ?>_insert'));
  7.     dataInspector.setRemoveWidget(document.getElementById('<?php echo $id; ?>_remove'));
  8.  
  9.     dataInspector.setShiftWidget(document.getElementById('<?php echo $id; ?>_shift'));
  10.     dataInspector.setUnshiftWidget(document.getElementById('<?php echo $id; ?>_unshift'));

Associe les boutons de contrôle avec leurs fonctions dans l'instance de SetOfInspector.

  1.     const title = new StringInspector('<?php echo $title; ?>', { escapeHTML: false });
  2.  
  3.     title.setManagedWidget(document.getElementById('<?php echo $id; ?>_title')).resetWidget();
  4.  
  5.     const legend = new BooleanInspector(false);
  6.  
  7.     legend.setManagedWidget(document.getElementById('<?php echo $id; ?>_legend')).resetWidget();
  8.  
  9.     const layoutInspector = new SequenceInspector({ title: title, legend: legend });

Crée les inspecteurs pour le titre et l'option d'affichage de la légende du graphique. Crée l'instance de SequenceInspector qui gère ces 2 inspecteurs.

  1.     const inspectors = {
  2.         data:       dataInspector,
  3.         layout:     layoutInspector
  4.     };
  5.  
  6.     const editor = new Editor(model, plotly, inspectors, panel);

Crée l'instance de Editor qui va coordonner les communications entre le modèle de données, l'affichage du graphique, les inspecteurs et le panneau avec les boutons pour défaire ou refaire une action.

  1.     model.setDelegate(new ModelCookieDelegate());
  2.  
  3.     if (model.isSaved())
  4.         model.readIn();
  5.     else
  6.         _init()
  7.  
  8.     model.enableSync();

Configure l'enregistrement du modèle de données dans un cookie. Si possible, initialise le modèle avec la dernière sauvegarde. Sinon, appelle la fonction _init. Enregistre automatiquement le modèle de données après qu'une de ses valeurs a été modifiée.

  1.     function _init() {
  2.         const data = [
  3.             { x: '1 2 3 4', y: '<?php list($c, $y)=$data[0]; echo implode(' ', $y); ?>', markercolor: '<?php echo $c; ?>' },
  4.             { x: '1 2 3 4', y: '<?php list($c, $y)=$data[1]; echo implode(' ', $y); ?>', markercolor: '<?php echo $c; ?>' },
  5.             { x: '1 2 3 4', y: '<?php list($c, $y)=$data[2]; echo implode(' ', $y); ?>', markercolor: '<?php echo $c; ?>' },
  6.             { x: '1 2 3 4', y: '<?php list($c, $y)=$data[3]; echo implode(' ', $y); ?>', markercolor: '<?php echo $c; ?>' }
  7.         ];
  8.         const layout = { title: '<?php echo $title; ?>', legend: false }
  9.  
  10.         model.set({ data: data, layout: layout }).sync();
  11.     }

La fonction locale _init initialise le modèle de données et l'enregistre.

  1.     const reset = document.getElementById('<?php echo $id; ?>_reset');
  2.  
  3.     reset.onclick = _init;

Appelle _init quand le bouton de remise à zéro est cliqué.

  1. <?php if (!$debug): ?>
  2. })();
  3. <?php endif; ?>

Ferme la fonction qui isole le code en JavaScript si $debug vaut false.

VOIR AUSSI

Responder, RangeInspector, ColorInspector, SequenceInspector, SetOfInspector, Model, ModelCookieDelegate, Editor, Architecture d'un éditeur

Commentaires

Votre commentaire :
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip aide 2000

Entrez un maximum de 2000 caractères.
Améliorez la présentation de votre texte avec les balises de formatage suivantes :
[p]paragraphe[/p], [b]gras[/b], [i]italique[/i], [u]souligné[/u], [s]barré[/s], [quote]citation[/quote], [pre]tel quel[/pre], [br]à la ligne,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].