Visualization of medical data using D3.js (ii) Legend (Legend) __js

Source: Internet
Author: User
introduce

At the end of the previous article, we mentioned a number of areas to be improved on the generated visual graph. Here we will discuss the display of the legend.

The main purpose of the legend is to describe the contents and indicators of the symbols and colors represented in the chart. For the line chart we generated earlier, we need to use a legend to illustrate what each curve means. The basic principles of the two-point summary are as follows:

1. The color of the corresponding curve in the legend, and indicate the name of the corresponding medical institution;

2. The legend should be placed in the appropriate position in order to play an appropriately indicative role.

This article will implement two different implementations and discuss their differences.

code Example

<!
    DOCTYPE html> <html> <head> <meta charset= "Utf-8" > <title> National Medical Service Volume </title> <link rel= "stylesheet" type= "Text/css" href= "Css/styles.css"/> "<script type=" Text/javascript "src=" js/d3.m In.js "></script> </head> <body> <script type=" Text/javascript "> Function Linechart () {VA

    R _chart = {}; var _width = screen.width * 0.9, _height = +, _margins = {top:30, left:50, right:130, bottom:60},//exp and margin for legend Rendor _legendbottom =-//area for Legend in method 2 _legendright = 10
            0,//area for Legend in Method 1 _x, _y, _names = [],//keep Name list for the chart _data = [],//_colors = D3.scale.category10 (), _colors,//define colors-according to name Li

    St _svg, _bodyg, _line;
     _chart.render = function () {if (!_svg) {       _svg = D3.select ("Body"). Append ("div"). Style ("Text-align", "center"). Append ("SVG")

            . attr ("height", _height). attr ("width", _width);

            Renderaxes (_SVG);
        Definebodyclip (_SVG);
    } renderbody (_svg);

    };

        function Renderaxes (SVG) {var axesg = svg.append ("G"). attr ("Class", "axes");

        Renderxaxis (AXESG);
    Renderyaxis (AXESG); function Renderxaxis (AXESG) {var xaxis = D3.svg.axis (). Scale (_x.range ([0, Quadrantwidt        

        H ()])). Orient ("bottom");
                    Axesg.append ("G"). attr ("Class", "X axis"). attr ("Transform", function () {
                Return "translate (" + xstart () + "," + ystart () + ")";
                
        ). Call (Xaxis); D3.selectall ("g.x G.tick"). Append ("line"). CLassed ("Grid-line", True). attr ("x1", 0). attr ("Y1", 0). attr ("X2", 0)
    . attr ("Y2",-quadrantheight ()); The function Renderyaxis (AXESG) {var yaxis = D3.svg.axis (). Scale (_y.range ([Quadrantheight (
                
        ), 0]). Orient ("left");
                    Axesg.append ("G"). attr ("Class", "Y axis"). attr ("Transform", function () {
                Return "translate (" + xstart () + "," + yend () + ")";
                
         ). Call (YAxis); D3.selectall ("G.y G.tick"). Append ("line"). Classed ("Grid-line", True). attr ("
    X1 ", 0). attr (" Y1 ", 0). attr (" X2 ", Quadrantwidth ()). attr (" Y2 ", 0);

        function Definebodyclip (SVG) {var padding = 5;
               Svg.append ("Defs"). Append ("Clippath") . attr ("id", "Body-clip"). Append ("Rect"). attr ("x", 0-padding). attr ("Y
                ", 0). attr (" width ", quadrantwidth () + 2 * padding + _legendright)//expand clip path for Legend
    . attr ("Height", quadrantheight ()); } function Renderbody (SVG) {if (!_bodyg) _bodyg = Svg.append ("G"). attr ("CLA 
                        SS "," Body "). attr (" transform "," translate "+ xstart () +", "        

        + yend () + ")"). attr ("Clip-path", "url (#body-clip)");

        Renderlines ();
        
        Renderdots ();
    Method 2:put legend at the bottom of the chart renderlegend ();  function Renderlines () {_line = D3.svg.line (). x (function (d) {return _x (d.date);
                        
        }. Y (function (d) {return _y (d.value);}); _bodyG.selectall ("G.linegroup path.line"). Data (_data). Enter (). Append ("G" ). attr ("Class", "Linegroup"). Append ("path"). Style ("Stro
                Ke ", function (d, i) {return _colors (_names[i]);
        
        }). attr ("Class", "line");

        _bodyg.selectall ("G.linegroup path.line"). Data (_data). Exit (). Remove (); _bodyg.selectall ("G.linegroup path.line"). Transition (). Duration (1000). A
        
        TTR ("D", function (d) {return _line (d);}); Method 1:add legend along with the line _bodyg.selectall ("G.linegroup"). Append ("text"). Datu   M (function (d, i) {return {name: _names[i], date:d[d.length-1].date, value:d[d.length-1].value}; Get the ' last point ' of the Line}). attr ("transform", function (d) {return "translate" ("+" (_x (d.date) + 5) + "," + _y (d.value) + ")"; Set the legend beside the last point}). attr ("X", 3). attr ("dy", ". 35em"). Classed ( 
	        "LegendText", True). Text (function (d) {return d.name;
    });
                        function Renderdots () {_data.foreach (function (list, i) {_bodyg.selectall ("circle._" + i) . data (list). Enter (). Append ("Circle"). A
            
            TTR ("Class", "dot _" + i);

            _bodyg.selectall ("circle._" + i). Data (list). exit (). Remove (); _bodyg.selectall ("circle._" + i). Data (list). Style ("Stroke",
                    function (d) {return _colors (_names[i]); }). Transition (). Duration(1000). attr ("CX", function (d) {return _x (d.date);})
                    . attr ("Cy", function (d) {return _y (d.value);})
        . attr ("R", 3.5);
    }); }//render legend at the bottom of the chart function renderlegend () {var legend = _svg.selectall (". Lege nd "). Data (_colors.domain ()). Enter (). Append (" G "). attr (" Class "," Legend "). attr (" Transform ", function (d,   i) {var legendx = i * + _margins.left;
				Set position for each legend element var Legendy = _height-_legendbottom;
			Return "translate (" + Legendx + "," + Legendy + ")";
		
		}); Legend.append ("rect"). attr ("X", 0). attr ("Y", 1). attr ("width"). attr ("height", 8). Style ("Fill", _col
		
		ORS);  Legend.append ("text"). attr ("x"). attr ("Y", 9). Classed ("LegendText", True). Text (function (d) {return
			D
    });
    function Xstart () {return _margins.left; } function Ystart () {return _height-_margins.bottom;
    function Xend () {return _width-_margins.right;
    function Yend () {return _margins.top;
    function Quadrantwidth () {return _width-_margins.left-_margins.right;
    function Quadrantheight () {return _height-_margins.top-_margins.bottom;
        } _chart.width = function (w) {if (!arguments.length) return _width;
        _width = W;
    return _chart;

    };
        _chart.height = function (h) {if (!arguments.length) return _height;
        _height = h;
    return _chart;

    };
        _chart.margins = function (m) {if (!arguments.length) return _margins;
        _margins = m;
    return _chart;

    };
        _chart.colors = function (c) {if (!arguments.length) return _colors;
        _colors = C;
    return _chart;
    
    }; Set Name list function _chart.names = function (n) {if!arguments.length) return _names;
        _names = n;
    return _chart;

    };
        _chart.x = function (x) {if (!arguments.length) return _x;
        _x = x;
    return _chart;

    };
        _chart.y = function (y) {if (!arguments.length) return _y;
        _y = y;
    return _chart;

    };
        _chart.addseries = function (series) {_data.push (series);
    return _chart;

    };
return _chart;

function Randomdata () {return math.random () * 9;}
        function Update () {for (var i = 0; i < data.length ++i) {var series = Data[i];
        series.length = 0;
    for (var j = 0; j < Numberofdatapoint; ++j) Series.push ({x:j, Y:randomdata ()});
} chart.render ();
}//load data var names = [];
var data = [];
var minvalue = 0, MaxValue = 0;

var mindate = 0, maxdate = 0;

var TimeFormat = D3.time.format ("%y-%m");

var chart; D3.text ("Data/health-service-quantity.json", function (rawdatastr) {var rawdata = JSOn.parse (RAWDATASTR);
	Names = D3.keys (rawdata); Names.foreach (function (name) {var list = Rawdata[name].map (function (item) {return {"date": Timeformat.parse (item
		
		. Date), "Value": Item.value}});			
		Get min and Max value if (minvalue = 0) {MinValue = d3.min (list, function (d) {return d.value;});
		}else{MinValue = D3.min ([MinValue, d3.min (list, function (d) {return d.value;})];
		
		} MaxValue = D3.max ([MaxValue, D3.max (list, function (d) {return d.value;})];
		Get min and Max date if (mindate = 0) {mindate = d3.min (list, function (d) {return d.date;});
		} if (maxdate = = 0) {maxdate = D3.max (list, function (d) {return d.date;});
	} data.push (list);
	
	}); Chart = Linechart (). x (D3.time.scale (). Domain ([mindate, MaxDate]). Y (D3.scale.linear (). domain ([minvalue * 0.5, MAXV
	
	Alue * 1.02]));
	Data.foreach (function (series) {chart.addseries (series);
	
	});
	Set Name list to the chart chart.names (names); Define Colors AccordinG to Name list chart.colors (D3.scale.category10 (). Domain (names));
Chart.render ();

}); </script> </body> </html>

Visualization Results

As you can see, one of the implementation methods (method one) puts the legend directly behind the curve (the principle can refer to [1]), while the other method (method two) places the legend set below the chart.


discussion

First look at the implementation method. There are several basic concepts in the implementation of the legend above.

First, either way, you need to pass the names in to the chart to display the name of the medical institution in the legend. Second, the corresponding relationship between the name list and the colors needs to be clearly defined so that the associated relationship with the curve is maintained in the legend.

In addition to some of the common places above, method one of the key two points, one is to put the text of the legend next to the position of the last point of the curve, the second is to keep the text of the legend to the right blank. In this example, because of the use of Clippath, the scope of the Clippath also needs to be covered to the scope of the legend.

Method Two also need to leave enough space for the legend below the chart. In addition, the appropriate legend layout should be set up. The current implementation is evenly spaced as a row because of its wide enough width. You can also set the appropriate calculations to perform other forms of typesetting, such as arranging multiple lines or arranging them vertically.

After adding the legend generated by both methods, the layout of the entire chart above is shown in the following illustration.


From the present realization effect, the first method occupies the horizontal space, the advantage is that the legend followed the curve, so that users of each curve represents the data at a glance. But its flaws are obvious, and different legend names may overlap and not be seen clearly. The second approach is a comparison of the standard legend placement method, occupies the vertical space, there is no particularly obvious defects. For the current line graph, the second method of personal feeling is more appropriate. Of course, for each of the different charts, you need to choose the way in which the legend is presented, depending on its actual situation.

Reference Documents

1. Multi-series line Chart. http://bl.ocks.org/mbostock/3884955

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.

Tags Index: