Check out Sunborn's two newly announced games (official English titles pending): Girls' Frontline: Blue Butterfly Contract and Reverse Collapse: F !
You don't need an account to join in. Learn how to contribute, browse Bounties and join our Discord server.

Widget:StatsGraph: Difference between revisions

Welcome to IOP Wiki. This website is maintained by the Girls' Frontline community and is free to edit by anyone.
Jump to navigation Jump to search
m Wrong variable
Create a script scope with IIFE shenanigans
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
<includeonly><div class="stats-graph-container"><script>
<includeonly><div class="stats-graph-container"><script>(() => {
function calcCoordinate(degree, min, max, val) {
   var targetContainer = document.currentScript.parentNode;
 
   RLQ.push(['ext.gadget.md5hasher', function () {
  var oldX = 0;
     $(document).ready(function() {
  var oldY = (max-min) == 0 ? 0 : -(300 / (max-min)) * (val - min);
       var graphData = JSON.parse(`<!--{$data|escape:'html'}-->`.replace(/&quot;/gi, '"'));
 
      window.iopwidgets.StatsGraph.buildGraph(graphData, targetContainer);
  if (degree == 0) {
    });
    return [oldX, Math.floor(oldY)];
  }]);
  }
})();</script></div></includeonly><noinclude>{{Documentation}}</noinclude>
 
   var rotate = (-degree * Math.PI) / 180;
 
  var newX = oldX*Math.cos(rotate)+oldY*Math.sin(rotate);
   var newY = oldY*Math.cos(rotate)+oldX*Math.sin(rotate);
  return [Math.floor(newX), Math.round(newY)];
}
 
function buildPolygonString(data) {
  var ret = "";
  var degreeSpacing = 360 / data.length;
  for (var i=0;i<data.length;i++) {
    var coord = calcCoordinate(degreeSpacing*i, data[i].min, data[i].max, data[i].value);
    ret += coord[0] + "," + coord[1] + " ";
  }
  ret = ret.trim();
  return ret;
}
 
function buildGraph(dataComplete) {
  var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  var svgNS = svg.namespaceURI;
  var svgLinkNS = "http://www.w3.org/1999/xlink";
  svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", svgLinkNS);
  svg.setAttribute('viewBox', "0 0 800 800");
  svg.setAttribute('preserveAspectRatio', "xMidyMid meet");
  svg.setAttribute('width', "300px");
  svg.setAttribute('height', "auto");
  svg.setAttribute('version', "1.1");
 
  /* This pretty much defines the base net lines */
  var defs = document.createElementNS(svgNS, 'defs');
 
  /* Wedge id has to be unique */
  var wedgeId = "wedge-" + 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
     var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
 
  var wedge = document.createElementNS(svgNS, 'g');
  wedge.setAttribute('id', wedgeId);
 
  var directionCount = dataComplete[0].data.length;
  var degreeSpacing = 360 / directionCount;
 
  var radialLine = document.createElementNS(svgNS, 'line');
  radialLine.setAttribute('class', 'radial');
  radialLine.setAttribute('y2', -325);
  wedge.appendChild(radialLine);
 
  for (var lineIdx=1;lineIdx<5;lineIdx++) {
    var orientationLine = document.createElementNS(svgNS, 'line');
    var lineDistance = lineIdx * -75;
    var rotate = (degreeSpacing * Math.PI) / 180;
    orientationLine.setAttribute('y1', lineDistance);
    orientationLine.setAttribute('x2', lineDistance*Math.sin(rotate));
    orientationLine.setAttribute('y2', lineDistance*Math.cos(rotate));
    if (lineIdx % 2 == 0) {
       orientationLine.setAttribute('class', 'emphased');
    }
    wedge.appendChild(orientationLine);
  }
  defs.appendChild(wedge);
  svg.appendChild(defs);
 
  // Now start drawing
  var gDrawing = document.createElementNS(svgNS, 'g');
  gDrawing.setAttribute('transform', 'translate(400 400)');
 
  for (var dataIdx=0; dataIdx<directionCount; dataIdx++) {
    var propertyLine = document.createElementNS(svgNS, 'use');
    propertyLine.setAttributeNS(svgLinkNS, "href", "#" + wedgeId);
    propertyLine.setAttribute('transform', "rotate(" + (degreeSpacing * dataIdx) + ")");
    gDrawing.appendChild(propertyLine );
  }
 
  for (var dataIdx=0; dataIdx<dataComplete.length; dataIdx++) {
    var polygonParams = dataComplete[dataIdx];
    var datapresentation = document.createElementNS(svgNS, 'polygon');
   
    if ('title' in polygonParams) {
      var title = document.createElementNS(svgNS, 'title');
      title.appendChild(document.createTextNode(polygonParams.title));
      datapresentation.appendChild(title);
    }
   
    if (('fill' in polygonParams) || ('stroke' in polygonParams)) {
      if ('fill' in polygonParams) datapresentation.setAttribute('fill', polygonParams.fill);
      if ('stroke' in polygonParams) datapresentation.setAttribute('stroke', polygonParams.stroke);
    } else {
      datapresentation.setAttribute('class', polygonParams.class ? polygonParams.class : "graph-orange");
    }
    datapresentation.setAttribute('points', buildPolygonString(polygonParams.data));
    gDrawing.appendChild(datapresentation);
   
    for (var labelIdx=0; labelIdx<polygonParams.data.length; labelIdx++) {
      var polygonCornerData = polygonParams.data[labelIdx];
      var rotate = (-degreeSpacing * labelIdx * Math.PI) / 180;
     
      var label = document.createElementNS(svgNS, 'text');
      label.setAttribute('x', -340*Math.sin(rotate));
      label.setAttribute('y', -340*Math.cos(rotate));
      label.setAttribute('title', titleText);
      label.appendChild(document.createTextNode(polygonCornerData.label));
 
      var titleText = "" + polygonCornerData.min + " <= " + polygonCornerData.value + " <= " + polygonCornerData.max;
      var title = document.createElementNS(svgNS, 'title');
      title.appendChild(document.createTextNode(titleText));
      label.appendChild(title);
     
      gDrawing.appendChild(label);
    }
  }
 
  svg.appendChild(gDrawing);
 
  var container = document.currentScript.parentNode;
  container.appendChild(svg);
}
 
var graphData = JSON.parse(`<!--{$data|escape:'html'}-->`.replace(/&quot;/gi, '"'));
buildGraph(graphData);</script></div></includeonly><noinclude>{{Documentation}}</noinclude>

Latest revision as of 19:29, 19 July 2025

Documentation[view] [edit] [history] [purge]

Widget to create an SVG image containing a radar chart. It is configured with a JSON string.

Parameters

Parameter name Required? Default value Description
data Yes (n/a) A JSON String containing all values. Please make sure that
  • There are at least three different properties to show. Anything below won't display correctly.
  • Each property needs a Label, Min, Max and Current value.
    • Label may be an empty string.
    • Min may be 0.

See the testcases for examples how to configure the JSON string.

Usage

See the template's testcases:


Small graph using default colors
Wiki code
{{#widget:StatsGraph
|data=[
  {
    "data": [
            { "label": "RoF", "min": 12, "max": 37, "value": 14 },
            { "label": "Acc", "min": 34, "max": 68, "value": 37 },
            { "label": "Dmg", "min": 9, "max": 12, "value": 11 }
          ]
  }
]}}
Main version
Sandbox version
Error in widget StatsGraph/sandbox: Unable to load template 'wiki:StatsGraph/sandbox'
Graph showing two graphs, second graph with different color
Wiki code
{{#widget:StatsGraph
|data=[
  {
    "data": [
            { "label": "RoF", "min": 12, "max": 37, "value": 32 },
            { "label": "Acc", "min": 12, "max": 37, "value": 32 },
            { "label": "Dmg", "min": 12, "max": 37, "value": 32 }
          ]
  },
  {
    "fill": "blue",
    "stroke": "darkblue",
    "data": [
            { "label": "RoF", "min": 12, "max": 37, "value": 34 },
            { "label": "Acc", "min": 34, "max": 68, "value": 51 },
            { "label": "Dmg", "min": 9, "max": 12, "value": 9 }
          ]
  }
]}}
Main version
Sandbox version
Error in widget StatsGraph/sandbox: Unable to load template 'wiki:StatsGraph/sandbox'
Graph with more properties
Wiki code
{{#widget:StatsGraph
|data=[
  {
    "data": [
            { "label": "RoF", "min": 12, "max": 37, "value": 14 },
            { "label": "Acc", "min": 34, "max": 68, "value": 37 },
            { "label": "Dmg", "min": 9, "max": 16, "value": 11 },
            { "label": "Dmg1", "min": 9, "max": 16, "value": 12 },
            { "label": "Dmg2", "min": 9, "max": 16, "value": 13 },
            { "label": "Dmg3", "min": 9, "max": 16, "value": 14 }
          ]
  }
]}}
Main version
Sandbox version
Error in widget StatsGraph/sandbox: Unable to load template 'wiki:StatsGraph/sandbox'