Cart Buy Licenses Contact Support Login/Register
v 1.8.4
v 1.8.4
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": "matrix",
          "name": "Quality",
          "title": "Please indicate if you agree or disagree with the following statements",
          "columns": [
            {
              "value": 1,
              "text": "Strongly Disagree"
            },
            {
              "value": 2,
              "text": "Disagree"
            },
            {
              "value": 3,
              "text": "Neutral"
            },
            {
              "value": 4,
              "text": "Agree"
            },
            {
              "value": 5,
              "text": "Strongly Agree"
            }
          ],
          "rows": [
            {
              "value": "affordable",
              "text": "Product is affordable"
            },
            {
              "value": "does what it claims",
              "text": "Product does what it claims"
            },
            {
              "value": "better then others",
              "text": "Product is better than other products on the market"
            },
            {
              "value": "easy to use",
              "text": "Product is easy to use"
            }
          ]
        },
        {
          "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(question, data) {
  var getData = function (visualizer) {
    var result = [Number.MAX_VALUE, Number.MIN_VALUE];
    visualizer.data.forEach(function (row) {
      var rowValue = row[visualizer.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, visualizer) {
    var data2render = getData(visualizer);
    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 new SurveyAnalytics.VisualizerBase(
    question,
    data,
    { renderContent: renderContent },
    "minMaxVisualizer"
  );
}

// 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(question, data) {
  var getData = function (visualizerBase) {
    var result = Number.MAX_VALUE;

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

    return result;
  };

  var renderContent = function (contentContainer, visualizer) {
    var data2render = getData(visualizer);
    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 new SurveyAnalytics.VisualizerBase(
    question,
    data,
    {
      renderContent: renderContent,
    },
    "minVisualizer"
  );
}

// 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";


// Custom visualizer displays matrix results in the table form
function CustomMatrixVisualizer(question, data) {
  function renderHeader(table, visualizer) {
    var header = document.createElement("tr");
    header.appendChild(document.createElement("th"));
    visualizer.valuesSource().forEach(function (value) {
      th = document.createElement("th");
      th.innerHTML = value.text;
      header.appendChild(th);
    });
    table.appendChild(header);
  }

  function renderRows(table, visualizer) {
    var data = visualizer.getData();
    visualizer.getSeriesLabels().forEach(function (label, rowIndex) {
      var tr = document.createElement("tr");
      var rowLabel = document.createElement("td");
      rowLabel.innerHTML = label;
      tr.appendChild(rowLabel);
      var sum = 0;
      data.forEach(function (colRow) {
        sum += colRow[rowIndex];
      });
      visualizer.valuesSource().forEach(function (_, columnIndex) {
        var cell = document.createElement("td");
        cell.innerHTML =
          data[columnIndex][rowIndex] +
          "(" +
          Math.round((data[columnIndex][rowIndex] / sum) * 100) +
          "%)";
        tr.appendChild(cell);
      });
      table.appendChild(tr);
    });
  }

  var renderContent = function (contentContainer, visualizer) {
    var table = document.createElement("table");
    table.className = "sa__matrix-table";
    renderHeader(table, visualizer);
    renderRows(table, visualizer);
    contentContainer.appendChild(table);
  };

  var matrixVis = new SurveyAnalytics.Matrix(
    question,
    data,
    {
      renderContent: renderContent,
    },
    "matrix_table"
  );
  return matrixVis;
}

// Register custom visualizer for the matrix question
SurveyAnalytics.VisualizationManager.registerVisualizer(
  "matrix",
  CustomMatrixVisualizer
);

// Set localized title of this visualizer
SurveyAnalytics.localization.locales["en"]["visualizer_matrix_table"] =
  "Table";

// Set localized title of the default visualizer
SurveyAnalytics.localization.locales["en"]["visualizer_matrix"] =
  "Charts";

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

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

var data = [
  
    {
        Quality: {
        affordable: "3",
        "does what it claims": "4",
        "better then others": "5",
        "easy to use": "1" },
        custom: { min: 4, max: 10 },
        bool: true,
        organization_type: "In-house",
        developer_count: "6-10"
    },
    {
        Quality: {
          affordable: "3",
          "does what it claims": "4",
          "better then others": "2",
          "easy to use": "3",
        },
        custom: { min: 3, max: 9 },
        bool: true,
        organization_type: "other",
        developer_count: "3-5",
    }
];

var visPanel = new SurveyAnalytics.VisualizationPanel(
    allQuestions,
    data,
    { labelTruncateLength: 27 }
);
visPanel.showHeader = true;
visPanel.render(panelNode);
$("#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">
<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>        <link href="/DevBuilds/packages/survey-analytics/survey.analytics.css" rel="stylesheet" />
        <script src="/DevBuilds/packages/survey-analytics/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>

#summaryContainer > .sa-question:nth-child(2) {
    width: 100%;
}
.sa__matrix-table {
    font-size: 14px;
    border-collapse: collapse;
    border: 1px solid black;
}
.sa__matrix-table td:first-child,
.sa__matrix-table th {
    font-weight: bold;
}
.sa__matrix-table th,
.sa__matrix-table td {
    padding: 10px;
    border: 1px solid black;
}