Buy Licenses Contact Support Login/Register
v 1.7.19
v 1.7.19
Overview Examples Docs Source Download

Custom visualizers

Create custom visualizers for a custom question type.

loading...

                        


    
        var json = {
  "completedHtml": "<p style='font-size:24px;'>Thank you for completing the survey! (please wait for analytics to load ...)<p>",
  "pages": [
    {
      "name": "page_info",
      "elements": [
        {
          "type": "custom-question",
          "name": "custom",
          "title": "This is a custom question with two values - min and max"
        },
        {
          "type": "radiogroup",
          "name": "organization_type",
          "title": "Which of the following best describes you or your organization?",
          "hasOther": true,
          "choices": [
            {
              "value": "ISV",
              "text": "ISV (building commercial/shrink wrapped software)"
            },
            {
              "value": "Consulting",
              "text": "Software consulting firm (provide development services to other organizations)"
            },
            {
              "value": "Custom",
              "text": "Custom software development (as a freelancer/contractor)"
            },
            {
              "value": "In-house",
              "text": "In-house software development"
            },
            {
              "value": "Hobbyist",
              "text": "Hobbyist (develop apps for personal use)"
            }
          ],
          "colCount": 2
        },
        {
          "type": "radiogroup",
          "name": "developer_count",
          "visibleIf": "{organization_type} != 'Hobbyist'",
          "title": "How many software developers are in your organization?",
          "choices": [ "1", "2", "3-5", "6-10", "> 10" ]
        }
      ]
    }
  ]
};
    
    // Register the custom question type
    // Lets the question collects two values - min and max
    // Question value is an object like { min: 3, max: 9 }
    Survey.Serializer.addClass("custom-question", [], null, "text");

    // Custom visualizer finds min and max values across all the answers on this question and shows them
    function CustomVisualizer(targetElement, question, data) {
      var self = this;
      self.targetElement = targetElement;
      self.question = question;
      self.data = data;
      self.toolbarItemCreators = {};

      var getData = function() {
        var result = [Number.MAX_VALUE, Number.MIN_VALUE];

        self.data.forEach(function(row) {
          var rowValue = row[self.question.name];
          if (!!rowValue) {
            if(rowValue.min < result[0]) {
              result[0] = rowValue.min;
            }
            if(rowValue.max > result[1]) {
              result[1] = rowValue.max;
            }
          }
        });

        return result;
      };

      var renderContent = function(contentContainer) {
        var data2render = getData();
        var minEl = document.createElement("div");
        var minTextEl = document.createElement("span");
        minTextEl.innerText = "Min: ";
        var minValEl = document.createElement("span");
        minValEl.innerText = data2render[0];
        minEl.appendChild(minTextEl);
        minEl.appendChild(minValEl);
        contentContainer.appendChild(minEl);
        var maxEl = document.createElement("div");
        var maxTextEl = document.createElement("span");
        maxTextEl.innerText = "Max: ";
        var maxValEl = document.createElement("span");
        maxValEl.innerText = data2render[1];
        maxEl.appendChild(maxTextEl);
        maxEl.appendChild(maxValEl);
        contentContainer.appendChild(maxEl);
      };

      return {
        name: "minMaxVisualizer",
        render: function(targetElement) {
          self.targetElement = targetElement || self.targetElement;

          var toolbarNodeContainer = document.createElement("div");
          var contentContainer = document.createElement("div");
          contentContainer.className = "sa-visualizer__content";

          renderContent(contentContainer);

          var toolbar = document.createElement("div");
          toolbar.className = "sva-toolbar";
          toolbarNodeContainer.appendChild(toolbar);
          SurveyAnalytics.VisualizerBase.prototype.createToolbarItems.apply(self, [toolbar]);

          self.targetElement.appendChild(toolbarNodeContainer);
          self.targetElement.appendChild(contentContainer);
        },
        registerToolbarItem: function(itemName, creator) {
            SurveyAnalytics.VisualizerBase.prototype.registerToolbarItem.apply(self, [itemName, creator]);
        },
        update: function(data) {
            self.data = data;
        },
        destroy: function() {
            self.targetElement.innerHTML = "";
        }
      };
    }

    // Register custom visualizer for the given question type
    SurveyAnalytics.VisualizationManager.registerVisualizer("custom-question", CustomVisualizer);
    // Set localized title of this visualizer
    SurveyAnalytics.localization.locales["en"]["visualizer_minMaxVisualizer"] = "Min/Max Values";

    // Custom visualizer finds min value across all the answers on this question and shows it
    function CustomMinVisualizer(targetElement, question, data) {
        var self = this;
        self.targetElement = targetElement;
        self.question = question;
        self.data = data;
        self.toolbarItemCreators = {};

        var getData = function() {
          var result = Number.MAX_VALUE;

          self.data.forEach(function(row) {
            var rowValue = row[self.question.name];
            if (!!rowValue) {
              if(rowValue.min < result) {
                result = rowValue.min;
              }
            }
          });

          return result;
        };

        var renderContent = function(contentContainer) {
          var data2render = getData();
          var minEl = document.createElement("div");
          var minTextEl = document.createElement("span");
          minTextEl.innerText = "Min: ";
          var minValEl = document.createElement("span");
          minValEl.innerText = data2render;
          minEl.appendChild(minTextEl);
          minEl.appendChild(minValEl);
          contentContainer.appendChild(minEl);
        };

        return {
          name: "minVisualizer",
          render: function(targetElement) {
            self.targetElement = targetElement || self.targetElement;

            var toolbarNodeContainer = document.createElement("div");
            var contentContainer = document.createElement("div");
            contentContainer.className = "sa-visualizer__content";

            renderContent(contentContainer);

            var toolbar = document.createElement("div");
            toolbar.className = "sva-toolbar";
            toolbarNodeContainer.appendChild(toolbar);
            SurveyAnalytics.VisualizerBase.prototype.createToolbarItems.apply(self, [toolbar]);

            self.targetElement.appendChild(toolbarNodeContainer);
            self.targetElement.appendChild(contentContainer);
          },
          registerToolbarItem: function(itemName, creator) {
              SurveyAnalytics.VisualizerBase.prototype.registerToolbarItem.apply(self, [itemName, creator]);
          },
          update: function(data) {
            self.data = data;
          },
          destroy: function() {
            self.targetElement.innerHTML = "";
          }
        };
    }

    // Register the second custom visualizer for the given question type
    SurveyAnalytics.VisualizationManager.registerVisualizer("custom-question", CustomMinVisualizer);
    // Set localized title of this visualizer
    SurveyAnalytics.localization.locales["en"]["visualizer_minVisualizer"] = "Min Value Only";

    var survey = new Survey.Model(json);
    var allQuestions = survey.getAllQuestions();

    var panelNode = document.getElementById("vizPanel");
    panelNode.innerHTML = "";

    var data = [
        {
            custom: { min: 4, max: 10 },
            bool: true,
            organization_type: "In-house",
            developer_count: "6-10"
        },
        {
            custom: { min: 3, max: 9 },
            bool: true,
            organization_type: "other",
            developer_count: "3-5",
        }
    ];

    var normalizedData = data.map(function (item) {
        survey.getAllQuestions().forEach(function (q) {
            if (item[q.name] === undefined) {
                item[q.name] = "";
            }
        });
        return item;
    });

    var visPanel = new SurveyAnalytics.VisualizationPanel(
        panelNode,
        allQuestions,
        normalizedData
    );
    visPanel.showHeader = true;
    visPanel.render();
    $("#loadingIndicator").hide();

                    
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Create custom visualizers for a custom question type., jQuery Survey Library Example</title>

<meta name="viewport" content="width=device-width" />
    <script src="https://unpkg.com/jquery"></script>
<script src="/DevBuilds/packages/survey-jquery/survey.jquery.js"></script>
    <link rel="stylesheet" href="./index.css">
<link href="https://surveyjs.azureedge.net/1.7.19/survey.analytics.css" rel="stylesheet" />

<script src="https://cdn.rawgit.com/inexorabletash/polyfill/master/typedarray.js"></script>

<script src="https://polyfill.io/v3/polyfill.min.js"></script>

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

<script src="https://unpkg.com/wordcloud@1.1.0/src/wordcloud2.js"></script>

<!--<script src="https://surveyjs.azureedge.net/1.7.19/survey.core.js"></script>-->

<script src="https://surveyjs.azureedge.net/1.7.19/survey.analytics.js"></script>
</head>
<body>
    
<div id="loadingIndicator">
    <span>
        <div id="loading"><strong>loading...</strong><span></span></div>
    </span>
</div>
<div id="vizPanel"></div>
            <div id="surveyElement" style="display:inline-block;width:100%;">
            </div>
    <div id="surveyResult"></div>

<script type="text/javascript" src="./index.js"></script>

</body>
</html>