D3.js to realize the method of radar map _javascript skills

Source: Internet
Author: User
Tags cos getcolor sin radar

Objective

In a nutshell, D3.js,d3.js is a JavaScript library based on data manipulation documents. D3 helps you to bring energy to your data by using HTML, SVG, and CSS. D3 values Web standards to provide you with the full functionality of modern browsers, rather than giving you a proprietary framework. Combines powerful visual components and data-driven DOM operations. You can also see that it is using SVG to render the chart, so using d3.js requires a certain SVG base.

This article is still the first to put together a simple drawing frame to add an SVG canvas. This is similar to the pie chart, and for the sake of drawing later, we move the G element that combines these elements to the center of the canvas:

<! DOCTYPE html>  

Why do I say that radar and pie charts are a little bit similar? Take a look at this picture below.

As you can see, the screen axis (blue part) of the radar map is composed of multiple polygon, and the polygon is drawn just by using the characteristics of the radius of the circle, so it is very convenient to draw the original point from the beginning to the center of the canvas.

Analog data

Let's simulate some raw data first.

var data = {
 FieldNames: [' Language ', ' mathematics ', ' foreign language ', ' physics ', ' chemistry ', ' biology ', ' politics ', ' history '],
 values: [
  [10,20,30,40,50,60,70,80]
 ]
};

Compute the coordinate of the network axis and draw

In the implementation of the other diagrams above, there are some things such as scale or layout to facilitate our transformation of data, is there such a tool function in radar? The answer is NO! No! No! The important thing to say three times! (-_-) So, we can only start our own small brain to forget.

Set some easy to compute constants
var radius = m,
 //number of indicators, that is, total = 8 of the length of the FieldNames,
 //You need to divide the network axis into several levels, that is, how many positive polygons
 from small to big on the network axis Level = 4,
 //NET axis range, similar to axis
 rangemin = 0,
 RangeMax = m,
 arc = 2 * MATH.PI;
The angle of each indicator is
var onepiece = arc/total;
Compute the polygon coordinate of the network axis
var polygons = {
 webs: [],
 webpoints: []
};
for (Var k=level;k>0;k--) {
 var webs = ',
   webpoints = [];
 var r = radius/level * k;
 for (Var i=0;i<total;i++) {
  var x = R * Math.sin (i * onepiece),
   y = R * Math.Cos (i * onepiece);
  Webs + = x + ', ' + y + ';
  Webpoints.push ({
   x:x,
   y:y
  });
 Polygons.webs.push (webs);
 Polygons.webPoints.push (webpoints);

Computing the coordinates of the network axis is to compute the coordinates of each polygon, in order to add polygon elements to facilitate the drawing (points attribute), we need to find the coordinates of the time to put them into a string. In the for loop of the above code, the outer loop represents a polygon, the inner loop represents the point on the polygon, and the difference between the polygon and the polygon is only that the radius of their outer circle is different, and the difference between the points and points of the same polygon is different from their angle. The coordinates of a point are calculated by multiplying the radius by the sine or cosine of the angle.

After we get the calculated coordinates, we begin to add the network axis.

Draw the net axis
var webs = main.append (' g ')
  . Classed (' Webs ', true);
Webs.selectall (' polygon ')
  . Data (polygons.webs).
  enter ().
  append (' polygon ')
  . attr (' points '), function (d) {return
   D;
  });

Add a G element to combine all the elements representing the network axis, select the polygon element and bind the Polygons.webs array, and enter() append() add a new polygon element to replicate the points attribute. After completing this series of operations that have been practiced over and over in previous articles, let's add a little style to make the network axis more visible.

. Webs polygon {
 fill:white;
 fill-opacity:0.5;
 Stroke:gray;
 Stroke-dasharray:10 5;

We get the net axis as shown in the following figure.

Add Vertical axis

Then we add the longitudinal axis to it. A longitudinal axis is a line that adds a root, a point that connects the center point to the outermost polygon, and the data that is needed can be taken from the polygons.webPoints[0] middle.

Add vertical axis
var lines = main.append (' g ')
  . Classed (' lines ', true);
Lines.selectall (' line ')
  . Data (Polygons.webpoints[0])
  . Enter ()
  . Append (' line ').
  attr (' X1 ', 0)
  . attr (' y1 ', 0)
  . attr (' X2 ', function (d) {return
   d.x;
  })
  . attr (' y2 ', function (d) {return
   d.y;
  });

The axis portion of the radar chart is complete.

Compute the radar chart area and add

The radar area is also a polygon, just an irregular polygon. But his points are always on the longitudinal axis, and the position of the point on the longitudinal axis can be computed by the ratio of the value represented by the point in the range of the longitudinal axis.

Compute the coordinates of the radar chart
var areasdata = [];
var values = data.values;
for (Var i=0;i<values.length;i++) {
 var value = values[i], area
   = ',
   points = [];
 for (Var k=0;k<total;k++) {
  var r = Radius * (value[k]-rangemin)/(rangemax-rangemin);
  var x = R * Math.sin (k * onepiece),
   y = R * Math.Cos (k * onepiece);
  Area + = x + ', ' + y + ';
  Points.push ({
   x:x,
   y:y
  })
 }
 Areasdata.push ({
  polygon:area,
  points:points
 });
}

After calculating the coordinates of the point, we can add the radar map area. In order to make the radar chart more impressive, we also marked the dots on each longitudinal axis in addition to adding polygons to represent the area of the map.

//Add G Group contains all radar map area var areas = main.append (' g '). Classed (' areas ', true);///Add G Group to include a radar map The polygon under the area and the dot Areas.selectall (' g '). Data (Areasdata). Enter (). Append (' G '). attr (' class ', function (d, i) {return ' area
 ' + (i+1);
}); for (Var i=0;i<areasdata.length;i++) {//loop each radar map area var region = Areas.select ('. Areas ' + (i+1)), Areadata = Areasdat
 A[i]; Draw the Polygon area.append (' polygon ') under the radar map area. attr (' Points ', Areadata.polygon). attr (' stroke ', function (d, index) {R
   Eturn GetColor (i);
   }). attr (' Fill ', function (d, index) {return getcolor (i);
 });
 Plot the point var circles = area.append (' g ') under the radar map area. Classed (' circles ', true); Circles.selectall (' Circle '). Data (areadata.points). Enter (). Append (' Circle '). attr (' CX ', function (d) {RE
   Turn d.x;
   }). attr (' Cy ', function (d) {return d.y;
   }). attr (' R ', 3). attr (' stroke ', function (d, index) {return getcolor (i); 
}); }

Here in order to experience the hierarchical relationship, I use areas to contain all the radar map area, and in the inside with a G group to represent a radar map area, in the radar chart area contains the polygons and dots that make up the area. Here because our data is represented by a radar map area, the For loop only loops once. Add a style to the area you are drawing.

. Areas Polygon {
 fill-opacity:0.5;
 Stroke-width:3
}
. Areas Circle {
 fill:white;
 Stroke-width:3;
}

So I got a chart that looks like this.

Calculate text label coordinates and add

To make the chart more complete, let's add a text tag to it. The text label is labeled on the periphery of the network axis, so you can calculate the coordinates of the text label by the same principle of calculating the dot coordinate of the mesh axis polygon.

Compute text Label coordinates
var textpoints = [];
var Textradius = radius +;
for (Var i=0;i<total;i++) {
 var x = Textradius * Math.sin (i * onepiece),
   y = Textradius * Math.Cos (i * Onepiec e);
 Textpoints.push ({
  x:x,
  y:y
 });

Calculate the coordinates and add them to the canvas.

Draw text Label
var texts = main.append (' g ')
  . Classed (' texts ', true);
Texts.selectall (' text ')
  . Data (textpoints).
  Enter ()
  . Append (' text ').
  attr (' x ', function (d) {
   return d.x;
  })
  . attr (' Y ', function (d) {return
   d.y;
  })
  . Text (function (d,i) {return
   data.fieldnames[i];
  

The last look is like this.

Summarize

The above is the use of d3.js to achieve the full range of radar content, I hope this article for everyone's study and work can help. If you have questions you can leave a message, interested friends Please continue to pay attention to the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.