Chapter 2 Technical Implementation

2.1 Prerequisites

To execute the code samples in this article, I assume that you have an operational SoSci Survey project and are familiar with HTML, CSS, and JavaScript. For those not acquainted with these web technologies, I recommend importing the provided .xml file into SoSci Survey as a starting point for building your study.

In the code, %variable1% and %variable2% act as placeholders; they will be replaced with the actual scores obtained from the survey participants. Likewise, var_01 to var_12 should be replaced with the specific variables you intend to use in your project. Note that the ensuing code examples serve as foundational templates for creating the chart.

2.2 Calculation of participant indices

In the PHP code section, I calculate two indices,variable1 and variable2, by taking the mean of six distinct variables each. These calculated means are then formatted to one decimal place and are intended to be used in a chart. The code relies on a built-in function valueMean() to compute the average values.

  1. Calculating mean: For the first variable variable1is calculated using var_01 to var_06 and for variable2, var_07 to var_12 is used.
    $variable1= valueMean(array('var_01', 'var_02', 'var_03', 'var_04', 'var_05', 'var_06'));
    $variable2= valueMean(array('var_07', 'var_08', 'var_09', 'var_10', 'var_11', 'var_12'));
  1. Debugging: The debug($variable1) and debug($variable2) lines are for debugging purposes, presumably printing the calculated mean values to the log.
    debug($variable1);
    debug($variable2);
  1. String formatting and replacement: The sprintf('%1.1f', $variable1) and sprintf('%1.1f', $variable2) lines format the mean values to one decimal place. These formatted values replace %variable1% and %variable2%, which are placeholders likely used in a subsequent chart or report.
    replace('%variable1%', sprintf('%1.1f', $variable1));
    replace('%variable2%', sprintf('%1.1f', $variable2));

2.3 Bar plot: Code explanation

The code provided is an HTML/JavaScript snippet that uses the Chart.js library to render a bar chart. I compare the previously calculated variable1 and variable2 in this example. The chart is customized with specific colors for the background and border, as well as border width. The Y-axis scale is set to range between 1 and 7. This explanation will dissect the code, focusing on key elements like the data structure, aesthetic properties, and configuration options.

  1. Including Chart.js: The Chart.js library is included via a script tag, which is essential for rendering the chart.
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  1. Canvas element: A canvas element with the id barChart is created. This is where the chart will be rendered.
    <canvas id="barChart"></canvas>
  1. JavaScript code: The main JavaScript code does the following:
  • Context retrieval: The context of the canvas is obtained using
    var ctx = document.getElementById('barChart').getContext('2d');
  • Data and aesthetics: The data object contains labels (‘Label1’ and ‘Label2’) and datasets. The datasets have data points, background color, border color, and border width.
    data: {
      labels: ['Label1', 'Label2'],
      datasets: [{
        data: ['%variable1%', '%variable2%'],
        backgroundColor: 'rgba(178, 24, 43, 0.2)',
        borderColor: 'rgba(178, 24, 43, 1)',
        borderWidth: 1.5
      }]
    }
        
  • Options: One can set additional options like scales and plugins. Here, the Y-axis is limited to values between 1 and 7, and the legend is hidden.
    options: {
      scales: {
        y: {
          min: 1,
          max: 7
        }
      },
      plugins: {
        legend: { display: false }
      }
    }
        

2.3.1 Further customization

2.3.1.1 Fine tuning

One can further customize the backgroundColor, borderColor, and borderWidth by changing their respective values in the dataset object. For more colors, use any valid CSS color specification like hex, RGB, or RGBA values. One can also include error bars (represented as standard deviation, standard error or confidence interval).

2.3.1.2 Add comparable barplot

To add another barplot, we need to import or define more datapoints. For this, I extend the original bar chart code from above to include a comparable dataset. This allows for two bars per label, facilitating a side-by-side comparison of the datasets.

    data: {
      labels: ['Label1', 'Label2'],
      datasets: [{
        data: ['%variable1%', '%variable2%'],
        backgroundColor: 'rgba(178, 24, 43, 0.2)',
        borderColor: 'rgba(178, 24, 43, 1)',
        borderWidth: 1.5
      }, 
      {

    // add another dataset
      data: [3, 4],
        // ... other attributes
      }
      ]
    }
        

2.3.1.3 Hatching and error bars

For complex data visualization tasks, adding layers of interpretive features like hatching patterns and error bars can be valuable. This document outlines the procedure to implement these features using Chart.js. A custom Chart.js plugin named HatchingAndErrorBars is set and employed to simultaneously add hatching patterns and error bars to bars corresponding to the comparative study data. This plugin utilizes the afterDraw hook, leveraging canvas drawing methods for both functionalities.

  1. Initialization: The plugin object is initialized with an id and an afterDraw function.
const HatchingAndErrorBars = {
  id: 'HatchingAndErrorBars',
  afterDraw: (chart) => {
    // Code for drawing hatching and error bars
  }
};
  1. Canvas Context and Scales: Inside the afterDraw function, canvas context (ctx) and scales (yAxis) are extracted for drawing.
const { ctx } = chart;
const yAxis = chart.scales['y'];
  1. Dataset Index and Error Values: The index for the comparative study data is set to 1, and error values are defined as an array.
const datasetIndex = 1;  
const errorValues = [0.5, 0.4, 0.3, 0.6, 0.7];
  1. Drawing Hatching: The hatching is performed using a forEach loop that iterates through each bar in the dataset.
// Drawing hatching
meta.data.forEach((bar) => {
  // Canvas drawing code for hatching
});
  1. Drawing Error Bars: Error bars are added using another forEach loop that also iterates through each bar in the dataset.
// Drawing error bars
meta.data.forEach((bar, index) => {
  // Canvas drawing code for error bars
});
  1. Plugin Incorporation: Finally, the custom plugin is included during Chart object initialization by adding it to the plugins array.
// ... other attributes
  options: {
  },
  plugins: [HatchingAndErrorBars]
});

2.4 Radar plot: Code explanation

Similar to the previous chart, this code snippet implements the Chart.js library. It creates a radar chart with two labels: Label1 and Label2, and uses two variables (%variable1% and %variable2%) for plotting.

  1. Canvas element: Again, a canvas element with the id radarChart is defined. This serves as the rendering area for the radar chart.

    <canvas id="radarChart"></canvas>
  2. JavaScript context: The 2D rendering context of the canvas element is obtained, allowing drawing operations.

    var ctx = document.getElementById('radarChart').getContext('2d');
  3. JavaScript context: A new Chart object is instantiated with the type set to radar. The data object contains labels and datasets, where %variable1% and %variable2% are placeholders that would be replaced by actual values.

    new Chart(ctx, {
      type: 'radar',
      data: {
        labels: ['Label1', 'Label2'],
        datasets: [{
          data: ['%variable1%', '%variable2%']
        }]
      }
    });

2.4.1 Further customization

In the radar plot, fine-tuning and the addition of comparable data can be achieved in a manner similar to the bar plot. The following subsections delve into these features, highlighting their implementation in the radar plot’s JavaScript code.

2.4.1.1 Fine tuning

Just as in the bar plot, the radar plot allows for granular adjustments to visual elements like backgroundColor, borderColor, and borderWidth. These can be changed within the dataset object, providing control over the radar plot’s aesthetics.

2.4.1.2 Add comparable radarplot

Comparable data can be added to the radar plot in a way similar to the bar plot—by extending the datasets attribute within the data object. This allows for the overlay of normative scores with individual data points for direct comparison.

//norm data
label: 'Normwerte',
data: [2.74,3.13,3.27,2.70,2.70],
fill: true,
backgroundColor: [
  'rgba(75, 192, 192, 0.2)'
],
borderColor: [
  'rgba(75, 192, 192, 1)'
],
borderWidth: 1.5

By integrating these customization options, the radar plot, like the bar plot, can be tailored to more nuanced data representation needs. For a hands-on example of incorporating comparable data into a radar plot, refer to the practice example provided in Chapter 3.

2.5 Providing a downloadable PDF

The provided HTML and JavaScript code snippet demonstrates the use of jsPDF and html2canvas libraries to enable a client-side PDF download of a rendered chart. A button is provided, and upon clicking it, the canvas containing the chart is converted to an image, which is then embedded into a PDF file. This explanation will discuss the inclusion of the required libraries, the button’s functionality, and the JavaScript logic for converting the canvas to a PDF.

  1. Library inclusion: The jsPDF and html2canvas libraries are included to facilitate PDF creation and canvas-to-image conversion, respectively.

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
  2. Download button: A simple HTML button with the id downloadPdf is added, which will trigger the PDF download when clicked.

    <button id="downloadPdf">Download PDF</button>
  3. JavaScript logic: An event listener is attached to the button, and upon clicking, it performs the following operations:

    • Calls html2canvas to convert the canvas element to a PNG image.
    • Initializes a new jsPDF object.
    • Adds the image to the PDF.
    • Saves the PDF with the filename download.pdf.
    document.getElementById('downloadPdf').addEventListener('click', function() {
      html2canvas(document.getElementById('barChart'), {
        onrendered: function(canvas) {
          var imgData = canvas.toDataURL('image/png');
          var pdf = new jsPDF();
          pdf.addImage(imgData, 'PNG', 10, 10);
          pdf.save('download.pdf');
        }
      });
    });