Animated age pyramid: Difference between revisions
From JSXGraph Wiki
A WASSERMANN (talk | contribs) No edit summary |
A WASSERMANN (talk | contribs) No edit summary |
||
Line 181: | Line 181: | ||
* Now read the data | * Now read the data | ||
<source lang="javascript"> | <source lang="javascript"> | ||
function readFile(dataArr) { | |||
var len = dataArr.length, | |||
i, male, female, y, | |||
data = []; | |||
for (i=len-1;i>=0;i--) { | |||
if (i%3==2) { | |||
dataArr.splice(i,1); | |||
} else { | |||
if (i%3==1) { | |||
female = dataArr[i][3].replace(/ /g,'')*1; | |||
} else if (i%3==0) { | |||
y = dataArr[i][0]*1; | |||
male = dataArr[i][3].replace(/ /g,'')*1; | |||
data.push([y,male,female]); | |||
} | |||
dataArr[i].splice(0,4); // year,'',m/w,no, | |||
} | |||
} | |||
data.reverse(); | |||
ages = JXG.Math.Matrix.transpose(dataArr); | |||
return {matrix:ages, total: data}; | |||
}; | |||
var stat1 = readFile(dataV1W1EJ); | |||
</source> | |||
* Create for each year two filled rectangles (men, women) | |||
<source lang="javascript"> | |||
brd = JXG.JSXGraph.initBoard('jxgbox', {boundingbox:[-850,110,850,-10],axis:false}); | |||
createCurves(stat1,brd,'#658cb2','#b23f8c'); | |||
</source> | |||
===The complete JavaScript code=== | |||
<source lang="xml"> | |||
<script type="text/javascript" src="/ajax/ageV1W1EJ.js"></script> | |||
This animation shows data from the 12th coordinated Population Projection from the "[http://destatis.de Statistisches Bundesamt]". | |||
<jsxgraph width="500" height="500"> | |||
var i, t = '', yearIndex = 0, brd; | |||
var stat1 = readFile(dataV1W1EJ); | |||
function readFile(dataArr) { | |||
var len = dataArr.length, | |||
i, male, female, y, | |||
data = []; | |||
for (i=len-1;i>=0;i--) { | |||
if (i%3==2) { | |||
dataArr.splice(i,1); | |||
} else { | |||
if (i%3==1) { | |||
female = dataArr[i][3].replace(/ /g,'')*1; | |||
} else if (i%3==0) { | |||
y = dataArr[i][0]*1; | |||
male = dataArr[i][3].replace(/ /g,'')*1; | |||
data.push([y,male,female]); | |||
} | |||
dataArr[i].splice(0,4); // year,'',m/w,no, | |||
} | |||
} | |||
data.reverse(); | |||
ages = JXG.Math.Matrix.transpose(dataArr); | |||
return {matrix:ages, total: data}; | |||
}; | |||
brd = JXG.JSXGraph.initBoard('jxgbox', {boundingbox:[-850,110,850,-10],axis:false}); | |||
function createCurves(stat,brd, c1, c2) { | |||
var i, m = [], w = [], | |||
op = 1, | |||
off = 80, | |||
len = stat.matrix.length; | |||
for (i=0;i<len;i++) { | |||
m[i] = brd.create('curve',[[0],[0]], | |||
{fillColor:c1,strokeColor:c1, | |||
strokeOpacity:op,fillOpacity:op, | |||
strokeWidth:1, | |||
highlightFillColor:'yellow',highlightStrokeColor:'yellow'}); | |||
m[i].updateDataArray = (function(xArr, y) { return function() { | |||
this.dataX = [-off,-off-xArr[2*yearIndex]*1,-off-xArr[2*yearIndex]*1,-off,-off]; | |||
this.dataY = [y,y,y+1,y+1,y]; | |||
}; })(stat.matrix[i], i); | |||
JXG.addEvent(m[i].rendNode, 'mouseover', | |||
(function(g,d){ return function(){ | |||
g.highlight(); w[g._number].highlight(); setText(g._number); | |||
};})(m[i]), m[i]); | |||
JXG.addEvent(m[i].rendNode, 'mouseout', | |||
(function(g){ return function(){ | |||
g.noHighlight(); w[g._number].noHighlight(); | |||
};})(m[i]), m[i]); | |||
m[i].hasPoint = function(){return false;}; | |||
m[i]._number = i; | |||
w[i] = brd.create('curve',[[0],[0]], | |||
{fillColor:c2,strokeColor:c2, | |||
strokeWidth:1, | |||
strokeOpacity:op,fillOpacity:op, | |||
highlightFillColor:'yellow',highlightStrokeColor:'yellow'}); | |||
w[i].updateDataArray = (function(xArr, y) { return function() { | |||
this.dataX = [off,off+xArr[2*yearIndex+1]*1,off+xArr[2*yearIndex+1]*1,off,off]; | |||
this.dataY = [y,y,y+1,y+1,y]; | |||
}; } )(stat.matrix[i], i); | |||
JXG.addEvent(w[i].rendNode, 'mouseover', | |||
(function(g,d){ return function(){ | |||
g.highlight(); m[g._number].highlight(); setText(g._number); | |||
};})(w[i]), w[i]); | |||
JXG.addEvent(w[i].rendNode, 'mouseout', | |||
(function(g){ return function(){ | |||
g.noHighlight(); m[g._number].noHighlight(); | |||
};})(w[i]), w[i]); | |||
w[i].hasPoint = function(){return false;}; | |||
w[i]._number = i; | |||
} | |||
var t = brd.create('turtle',[],{strokeColor:'#999999', highlightStrokeColor:'#999999'}); t.ht().pu().rt(90); | |||
for (i=0;i<=90;i+=10) { | |||
t.moveTo([-750,i]).penDown().forward(750-off+10).penUp(); | |||
t.moveTo([off-10,i]).penDown().forward(750-off+10).penUp(); | |||
brd.create('text',[-15,i,i.toFixed(0)]); | |||
} | |||
return [m,w]; | |||
}; | |||
brd.suspendUpdate(); | |||
createCurves(stat1,brd,'#658cb2','#b23f8c'); | |||
brd.create('text',[-300,45,'men']/*,{strokeColor:'white',fontSize:20}*/); | |||
brd.create('text',[200,45,'women']/*,{strokeColor:'white',fontSize:20}*/); | |||
brd.unsuspendUpdate(); | |||
function changeYear() { | |||
yearIndex = document.getElementById('years').selectedIndex; | |||
setTextYear(); | |||
brd.update(); | |||
}; | |||
function setText(n) { | |||
var age = n, | |||
male = ages[n][2*yearIndex]*1, | |||
female = ages[n][2*yearIndex+1]*1; | |||
textout.innerHTML = 'age:'+age+ | |||
', born in '+(2009+yearIndex-age)+ | |||
'<br> male:'+male+ | |||
', female:'+female+ | |||
', together:'+(male+female)+ | |||
' (thousand)<br> ratio w/m:'+(female/male).toFixed(2); | |||
}; | |||
function setTextYear() { | |||
var n = yearIndex, | |||
data = stat1.total; | |||
textout2.innerHTML = 'Year:'+data[n][0]+ | |||
'<br> male:'+data[n][1]+ | |||
', female:'+data[n][2]+ | |||
', together:'+(data[n][1]+data[n][2])+ | |||
' (million)<br> ratio w/m:'+(data[n][2]/data[n][1]).toFixed(3); | |||
}; | |||
function animation() { | |||
yearIndex = (yearIndex+1)%52; | |||
document.getElementById('years').selectedIndex = yearIndex; | |||
setTextYear(); | |||
brd.update(); | |||
animate = setTimeout(animation,500); | |||
}; | |||
function player(){ | |||
if (!animate) { | |||
document.getElementById('playbutton').value = 'stop'; | |||
animation(); | |||
} else { | |||
document.getElementById('playbutton').value = 'play'; | |||
clearTimeout(animate); | |||
animate = null; | |||
} | |||
}; | |||
</jsxgraph> | |||
<form><select id="years" onChange="changeYear()"></select> | |||
<input type="button" id="playbutton" value="play" onClick="player();"> | |||
</form> | |||
<div id="output2" style="padding:20px; background-color:#bbbbbb; width:500px; font-family:Arial,Helvetica"> </div> | |||
<div id="output" style="padding:20px; background-color:#dddddd; width:500px; font-family:Arial,Helvetica"> </div> | |||
<script type="text/javascript"> | |||
var textout = document.getElementById('output'); | |||
var textout2 = document.getElementById('output2'); | |||
var animate = null; | |||
selectYear = document.getElementById('years'); | |||
var opt; | |||
for (i=2009;i<=2060;i++) { | |||
opt = document.createElement('option'); | |||
opt.text = i; | |||
try { | |||
selectYear.add(opt,null); | |||
} catch(e) { | |||
selectYear.add(opt); // IE | |||
} | |||
} | |||
setTextYear(); | |||
</script> | |||
</source> | </source> | ||
[[Category:Examples]] | [[Category:Examples]] | ||
[[Category:Charts]] | [[Category:Charts]] |
Revision as of 13:59, 23 November 2009
This animation shows data from the 12th coordinated Population Projection from the "Statistisches Bundesamt".
How to create this animation
- Download the data from destatis.de
- Save the table which should be displayed as csv file.
- Transform the csv file into a JavaScript file containing an 2 dimensional array:
dataV1W1EJ = [["2009"," ","m"," 40 070 "," 341 "," 350 "," 353 "," 348 ",...," 2 "],
[" "," ","w"," 41 665 "," 323 "," 333 "," 335 "," 329 ",...," 12 "],
[" "," ","i"," 81 735 "," 663 "," 683 "," 688 "," 677 ",...," 13 "],
["2010"," ","m"," 39 987 "," 339 "," 341 "," 350 "," 353 ",...," 2 "],
...
[" "," ","i"," 64 651 "," 465 "," 470 "," 476 "," 481 ",...," 169 "]];
Every third row labeled by 'i' in the third column will be deleted later on.
- Now read the data
function readFile(dataArr) {
var len = dataArr.length,
i, male, female, y,
data = [];
for (i=len-1;i>=0;i--) {
if (i%3==2) {
dataArr.splice(i,1);
} else {
if (i%3==1) {
female = dataArr[i][3].replace(/ /g,'')*1;
} else if (i%3==0) {
y = dataArr[i][0]*1;
male = dataArr[i][3].replace(/ /g,'')*1;
data.push([y,male,female]);
}
dataArr[i].splice(0,4); // year,'',m/w,no,
}
}
data.reverse();
ages = JXG.Math.Matrix.transpose(dataArr);
return {matrix:ages, total: data};
};
var stat1 = readFile(dataV1W1EJ);
- Create for each year two filled rectangles (men, women)
brd = JXG.JSXGraph.initBoard('jxgbox', {boundingbox:[-850,110,850,-10],axis:false});
createCurves(stat1,brd,'#658cb2','#b23f8c');
The complete JavaScript code
<script type="text/javascript" src="/ajax/ageV1W1EJ.js"></script>
This animation shows data from the 12th coordinated Population Projection from the "[http://destatis.de Statistisches Bundesamt]".
<jsxgraph width="500" height="500">
var i, t = '', yearIndex = 0, brd;
var stat1 = readFile(dataV1W1EJ);
function readFile(dataArr) {
var len = dataArr.length,
i, male, female, y,
data = [];
for (i=len-1;i>=0;i--) {
if (i%3==2) {
dataArr.splice(i,1);
} else {
if (i%3==1) {
female = dataArr[i][3].replace(/ /g,'')*1;
} else if (i%3==0) {
y = dataArr[i][0]*1;
male = dataArr[i][3].replace(/ /g,'')*1;
data.push([y,male,female]);
}
dataArr[i].splice(0,4); // year,'',m/w,no,
}
}
data.reverse();
ages = JXG.Math.Matrix.transpose(dataArr);
return {matrix:ages, total: data};
};
brd = JXG.JSXGraph.initBoard('jxgbox', {boundingbox:[-850,110,850,-10],axis:false});
function createCurves(stat,brd, c1, c2) {
var i, m = [], w = [],
op = 1,
off = 80,
len = stat.matrix.length;
for (i=0;i<len;i++) {
m[i] = brd.create('curve',[[0],[0]],
{fillColor:c1,strokeColor:c1,
strokeOpacity:op,fillOpacity:op,
strokeWidth:1,
highlightFillColor:'yellow',highlightStrokeColor:'yellow'});
m[i].updateDataArray = (function(xArr, y) { return function() {
this.dataX = [-off,-off-xArr[2*yearIndex]*1,-off-xArr[2*yearIndex]*1,-off,-off];
this.dataY = [y,y,y+1,y+1,y];
}; })(stat.matrix[i], i);
JXG.addEvent(m[i].rendNode, 'mouseover',
(function(g,d){ return function(){
g.highlight(); w[g._number].highlight(); setText(g._number);
};})(m[i]), m[i]);
JXG.addEvent(m[i].rendNode, 'mouseout',
(function(g){ return function(){
g.noHighlight(); w[g._number].noHighlight();
};})(m[i]), m[i]);
m[i].hasPoint = function(){return false;};
m[i]._number = i;
w[i] = brd.create('curve',[[0],[0]],
{fillColor:c2,strokeColor:c2,
strokeWidth:1,
strokeOpacity:op,fillOpacity:op,
highlightFillColor:'yellow',highlightStrokeColor:'yellow'});
w[i].updateDataArray = (function(xArr, y) { return function() {
this.dataX = [off,off+xArr[2*yearIndex+1]*1,off+xArr[2*yearIndex+1]*1,off,off];
this.dataY = [y,y,y+1,y+1,y];
}; } )(stat.matrix[i], i);
JXG.addEvent(w[i].rendNode, 'mouseover',
(function(g,d){ return function(){
g.highlight(); m[g._number].highlight(); setText(g._number);
};})(w[i]), w[i]);
JXG.addEvent(w[i].rendNode, 'mouseout',
(function(g){ return function(){
g.noHighlight(); m[g._number].noHighlight();
};})(w[i]), w[i]);
w[i].hasPoint = function(){return false;};
w[i]._number = i;
}
var t = brd.create('turtle',[],{strokeColor:'#999999', highlightStrokeColor:'#999999'}); t.ht().pu().rt(90);
for (i=0;i<=90;i+=10) {
t.moveTo([-750,i]).penDown().forward(750-off+10).penUp();
t.moveTo([off-10,i]).penDown().forward(750-off+10).penUp();
brd.create('text',[-15,i,i.toFixed(0)]);
}
return [m,w];
};
brd.suspendUpdate();
createCurves(stat1,brd,'#658cb2','#b23f8c');
brd.create('text',[-300,45,'men']/*,{strokeColor:'white',fontSize:20}*/);
brd.create('text',[200,45,'women']/*,{strokeColor:'white',fontSize:20}*/);
brd.unsuspendUpdate();
function changeYear() {
yearIndex = document.getElementById('years').selectedIndex;
setTextYear();
brd.update();
};
function setText(n) {
var age = n,
male = ages[n][2*yearIndex]*1,
female = ages[n][2*yearIndex+1]*1;
textout.innerHTML = 'age:'+age+
', born in '+(2009+yearIndex-age)+
'<br> male:'+male+
', female:'+female+
', together:'+(male+female)+
' (thousand)<br> ratio w/m:'+(female/male).toFixed(2);
};
function setTextYear() {
var n = yearIndex,
data = stat1.total;
textout2.innerHTML = 'Year:'+data[n][0]+
'<br> male:'+data[n][1]+
', female:'+data[n][2]+
', together:'+(data[n][1]+data[n][2])+
' (million)<br> ratio w/m:'+(data[n][2]/data[n][1]).toFixed(3);
};
function animation() {
yearIndex = (yearIndex+1)%52;
document.getElementById('years').selectedIndex = yearIndex;
setTextYear();
brd.update();
animate = setTimeout(animation,500);
};
function player(){
if (!animate) {
document.getElementById('playbutton').value = 'stop';
animation();
} else {
document.getElementById('playbutton').value = 'play';
clearTimeout(animate);
animate = null;
}
};
</jsxgraph>
<form><select id="years" onChange="changeYear()"></select>
<input type="button" id="playbutton" value="play" onClick="player();">
</form>
<div id="output2" style="padding:20px; background-color:#bbbbbb; width:500px; font-family:Arial,Helvetica"> </div>
<div id="output" style="padding:20px; background-color:#dddddd; width:500px; font-family:Arial,Helvetica"> </div>
<script type="text/javascript">
var textout = document.getElementById('output');
var textout2 = document.getElementById('output2');
var animate = null;
selectYear = document.getElementById('years');
var opt;
for (i=2009;i<=2060;i++) {
opt = document.createElement('option');
opt.text = i;
try {
selectYear.add(opt,null);
} catch(e) {
selectYear.add(opt); // IE
}
}
setTextYear();
</script>