{{ tocSubheader }}
| {{ 'ml-lesson-number-slides' | message : article.intro.bblockCount}} |
| {{ 'ml-lesson-number-exercises' | message : article.intro.exerciseCount}} |
| {{ 'ml-lesson-time-estimation' | message }} |
Henrik (Diskussion | bidrag) (Redigerar graf cirkeldiagram345a via JXMagician.) | Karin.hedin@osteraker.se (Diskussion | bidrag) | ||
Rad 3: | Rad 3: | ||
<translate>Cirkeldiagram är en typ av [[Diagram *Wordlist*|diagram]] som är användbart för att visa en '''fördelning''' av en helhet, till exempel hur eleverna i en skolklass som går ut nian fördelas på olika gymnasieprogram: några söker teknikprogrammet, några söker hantverksprogrammet \osv För att visualisera hur stora grupperna är i förhållande till varandra delas cirkeldiagrammet in i en bit per grupp</translate><t1>, <translate>där [[Medelpunktsvinkel *Wordlist*|medelpunktsvinkeln]] avgör [[Andel *Wordlist*|andelen]] en grupp utgör</translate></t1>. | <translate>Cirkeldiagram är en typ av [[Diagram *Wordlist*|diagram]] som är användbart för att visa en '''fördelning''' av en helhet, till exempel hur eleverna i en skolklass som går ut nian fördelas på olika gymnasieprogram: några söker teknikprogrammet, några söker hantverksprogrammet \osv För att visualisera hur stora grupperna är i förhållande till varandra delas cirkeldiagrammet in i en bit per grupp</translate><t1>, <translate>där [[Medelpunktsvinkel *Wordlist*|medelpunktsvinkeln]] avgör [[Andel *Wordlist*|andelen]] en grupp utgör</translate></t1>. | ||
− | <jsxgpre id=" | + | <jsxgpre id="cirkeldiagram_wordlist_fix" static=1> |
− | var b = mlg.board( | + | var b = mlg.board([0,4,7,0],{desktopSize:'medium'}); |
− | + | ||
− | //b. | + | var piechart = function(values, options) { |
− | b. | + | options = (options || {}); |
− | b. | + | if ('labels' in options) { |
− | + | if (options.labels.length != values.length) { | |
+ | throw "Number of labels does not match the number of values"; | ||
+ | } | ||
+ | } | ||
+ | if ('colors' in options) { | ||
+ | if (options.colors.length != values.length) { | ||
+ | throw "Number of colors does not match the number of values"; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | var fullOptions = { | ||
+ | startAngle:90, | ||
+ | clockwise:true, | ||
+ | useOrder:false, | ||
+ | precision:0, | ||
+ | percentLabels:false, | ||
+ | percentCutoff:8, | ||
+ | mathMode:false, | ||
+ | } | ||
+ | |||
+ | var defaultColors = [ | ||
+ | mlg.tikzColor('mltiny!60'), | ||
+ | mlg.tikzColor('mlhoy!60'), | ||
+ | mlg.tikzColor('mlhank!60'), | ||
+ | mlg.tikzColor('mlmary!60'), | ||
+ | mlg.tikzColor('mljoe!60'), | ||
+ | mlg.tikzColor('yellow!40'), | ||
+ | mlg.tikzColor('brown!60'), | ||
+ | mlg.tikzColor('pink!80'), | ||
+ | ] | ||
+ | |||
+ | var boxDimensions = b.board.attr.boundingbox; | ||
+ | |||
+ | fullOptions = overrideDict(fullOptions, options); | ||
+ | if ('colors' in fullOptions) { | ||
+ | defaultColors = fullOptions.colors; | ||
+ | } | ||
+ | |||
+ | var startAngle = fullOptions['startAngle']*2*Math.PI/360; | ||
+ | var direction = 1; | ||
+ | if (fullOptions['clockwise']) { | ||
+ | direction = -1; | ||
+ | } | ||
+ | |||
+ | var colors = []; | ||
+ | var labels = []; | ||
+ | |||
+ | //Om inget annat sägs ska delarna sättas i storleksordning | ||
+ | if (!fullOptions['useOrder']){ | ||
+ | var orderedValues = []; | ||
+ | var orderedColors = []; | ||
+ | var orderedLabels = []; | ||
+ | var newOrder = {}; | ||
+ | var whichAreTaken = []; | ||
+ | for (var i = 0; i < values.length; i++) { | ||
+ | var nLarger = 0; | ||
+ | for(var j = 0; j < values.length; j++) { | ||
+ | if (values[i] < values[j]) { | ||
+ | nLarger++; | ||
+ | } | ||
+ | } | ||
+ | while (whichAreTaken.indexOf(nLarger) != -1) { | ||
+ | nLarger++; | ||
+ | } | ||
+ | whichAreTaken.push(nLarger); | ||
+ | newOrder[nLarger.toString()] = i; | ||
+ | } | ||
+ | for (var i = 0;i < values.length; i++) { | ||
+ | var newIndex = newOrder[i.toString()]; | ||
+ | orderedValues.push(values[newIndex]); | ||
+ | if ('colors' in fullOptions) { | ||
+ | orderedColors.push(fullOptions.colors[newIndex]); | ||
+ | } | ||
+ | if ('labels' in fullOptions) { | ||
+ | orderedLabels.push(fullOptions.labels[newIndex]); | ||
+ | } | ||
+ | } | ||
+ | values = orderedValues; | ||
+ | colors = orderedColors; | ||
+ | labels = orderedLabels; | ||
+ | }else{ | ||
+ | if ('labels' in fullOptions){ | ||
+ | labels = fullOptions['labels']; | ||
+ | } | ||
+ | } | ||
+ | if (colors.length == 0) { | ||
+ | colors = defaultColors; | ||
+ | } | ||
+ | |||
+ | |||
+ | var sum = 0; | ||
+ | for (var i = 0; i < values.length;i++) { | ||
+ | sum += values[i]; | ||
+ | } | ||
+ | |||
+ | var degrees = [startAngle]; | ||
+ | for (var i = 0; i < values.length - 1;i++) { | ||
+ | degrees.push(degrees[i] + direction*values[i]/sum*2*Math.PI); | ||
+ | } | ||
+ | |||
+ | for (var i = 0; i < degrees.length;i++) { | ||
+ | if (degrees[i] < 0) { | ||
+ | degrees[i] = 2*Math.PI + degrees[i]; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | var radius = (boxDimensions[1] - boxDimensions[3])/2 * 0.9; | ||
+ | var centerY = (boxDimensions[1] + boxDimensions[3])/2; | ||
+ | var centerX = (boxDimensions[0] + boxDimensions[2])/2; | ||
+ | if ('labels' in fullOptions) { | ||
+ | centerX = 2/3*boxDimensions[0] + 1/3*boxDimensions[2]; | ||
+ | } | ||
+ | if ('position' in fullOptions) { | ||
+ | centerX = fullOptions.position[0]; | ||
+ | centerY = fullOptions.position[1]; | ||
+ | } | ||
+ | if ('chartOffset' in fullOptions) { | ||
+ | centerX += fullOptions['chartOffset']; | ||
+ | } | ||
+ | if ('radius' in fullOptions) { | ||
+ | radius = fullOptions['radius']; | ||
+ | } | ||
+ | var cNode = b.node(centerX, centerY); | ||
+ | |||
+ | |||
+ | //Side labels | ||
+ | if ('labels' in fullOptions) { | ||
+ | var labelX = (centerX + radius + boxDimensions[2])/2; | ||
+ | |||
+ | if ('position' in fullOptions) { | ||
+ | labelX = centerX + radius + (boxDimensions[2] - boxDimensions[0])/6; | ||
+ | } | ||
+ | |||
+ | var labelDist = (boxDimensions[1] - boxDimensions[3])/6; | ||
+ | if ('labelDistance' in fullOptions) { | ||
+ | labelDist = labelDist * fullOptions['labelDistance']; | ||
+ | } | ||
+ | |||
+ | var labelStart = centerY + (fullOptions['labels'].length-1)*labelDist/2; | ||
+ | if ('labelOffset' in fullOptions) { | ||
+ | labelX += fullOptions['labelOffset'][0]; | ||
+ | labelStart += fullOptions['labelOffset'][1]; | ||
+ | } | ||
+ | |||
+ | var longestLabel = labels[0]; | ||
+ | for (var i = 1; i < labels.length;i++) { | ||
+ | if (labels[i].length > longestLabel.length) { | ||
+ | longestLabel = labels[i]; | ||
+ | } | ||
+ | } | ||
+ | if ('phantomText' in fullOptions) { | ||
+ | longestLabel = fullOptions['phantomText']; | ||
+ | } | ||
+ | for (var i = 0;i < fullOptions['labels'].length;i++) { | ||
+ | b.txt(labelX, labelStart - i*labelDist, labels[i], {flag:true, flagColor:colors[i%colors.length], mathMode:fullOptions['mathMode'], phantomText:longestLabel}); | ||
+ | } | ||
+ | } | ||
+ | console.log(degrees); | ||
+ | |||
+ | //Percent labels | ||
+ | if (fullOptions['percentLabels']) { | ||
+ | var pct = []; | ||
+ | var pctCutoff = 0; | ||
+ | for (var i = 1;i < degrees.length + 1;i++) { | ||
+ | if (fullOptions['clockwise']) { | ||
+ | if (degrees[i%degrees.length] > degrees[i-1]) { | ||
+ | pct[i] = Math.abs(degrees[i%degrees.length]-degrees[i-1]-Math.PI*2)/(2*Math.PI)*100; | ||
+ | }else{ | ||
+ | pct[i] = Math.abs(degrees[i%degrees.length]-degrees[i-1])/(2*Math.PI)*100; | ||
+ | } | ||
+ | }else{ | ||
+ | if (degrees[i%degrees.length] < degrees[i-1]) { | ||
+ | pct[i] = (degrees[i%degrees.length]-degrees[i-1]+Math.PI*2)/(2*Math.PI)*100; | ||
+ | }else{ | ||
+ | pct[i] = (degrees[i%degrees.length]-degrees[i-1])/(2*Math.PI)*100; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (pct[i] < fullOptions['percentCutoff']) { | ||
+ | pctCutoff++; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (pctCutoff != 0){ | ||
+ | radius *= 0.8; | ||
+ | } | ||
+ | |||
+ | var pctLabelAng; | ||
+ | var pctLabelAngOff; | ||
+ | var tempTxt; | ||
+ | var fac; | ||
+ | for (var i = 1;i < degrees.length + 1;i++) { | ||
+ | pctLabelAng = (degrees[i%degrees.length]+degrees[i-1])/2; | ||
+ | if (fullOptions['clockwise']) { | ||
+ | if (degrees[i%degrees.length] > degrees[i-1]) { | ||
+ | pctLabelAng = Math.PI + pctLabelAng; | ||
+ | } | ||
+ | }else{ | ||
+ | if(degrees[i%degrees.length] < degrees[i-1]) { | ||
+ | pctLabelAng = Math.PI + pctLabelAng; | ||
+ | } | ||
+ | } | ||
+ | if (pct[i] < fullOptions['percentCutoff']) { | ||
+ | pctLabelAngOff = pctLabelAng; | ||
+ | if ('percentLabelsOffset' in fullOptions) { | ||
+ | if (degrees.length - i < fullOptions['percentLabelsOffset'].length) { | ||
+ | pctLabelAngOff = pctLabelAng + fullOptions['percentLabelsOffset'][degrees.length - i]/180*Math.PI; | ||
+ | } | ||
+ | } | ||
+ | fac = 1.29; | ||
+ | tempTxt = b.txt(centerX + radius*fac*Math.cos(pctLabelAngOff),centerY + radius*fac*Math.sin(pctLabelAngOff),pct[i].toFixed(fullOptions['precision']).toString() + '\\%',{fontsize:0.9}); | ||
+ | fac = 0.8 - Math.abs(Math.cos(pctLabelAngOff))/8; | ||
+ | b.segment([tempTxt.X()*fac + (centerX + radius*4/5*Math.cos(pctLabelAng))*(1-fac),tempTxt.Y()*fac + (centerY + radius*4/5*Math.sin(pctLabelAng))*(1-fac)],[centerX + radius*4/5*Math.cos(pctLabelAng),centerY + radius*4/5*Math.sin(pctLabelAng)],{strokeWidth:1}); | ||
+ | |||
+ | }else{ | ||
+ | b.txt(centerX + radius*2/3*Math.cos(pctLabelAng),centerY + radius*2/3*Math.sin(pctLabelAng),pct[i].toFixed(fullOptions['precision']).toString() + '\\%'); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | //Sectors | ||
+ | var firstNode = b.node(centerX + radius*Math.cos(degrees[0]), centerY + radius*Math.sin(degrees[0])); | ||
+ | var veryFirstNode = firstNode; | ||
+ | for (var i = 1; i < degrees.length;i++) { | ||
+ | var secondNode = b.node(centerX + radius*Math.cos(degrees[i]), centerY + radius*Math.sin(degrees[i])); | ||
+ | if (direction == -1) { | ||
+ | b.board.create('sector', [cNode, secondNode, firstNode], {strokeWidth:2, strokeColor:'black', opacity:1, fillColor:colors[(i-1)%colors.length]}); | ||
+ | } | ||
+ | else { | ||
+ | b.board.create('sector', [cNode, firstNode, secondNode], {strokeWidth:2, strokeColor:'black', opacity:1, fillColor:colors[(i-1)%colors.length]}); | ||
+ | } | ||
+ | firstNode = secondNode; | ||
+ | } | ||
+ | if (direction == -1) { | ||
+ | b.board.create('sector', [cNode, veryFirstNode, firstNode], {strokeWidth:2, strokeColor:'black', opacity:1, fillColor:colors[(degrees.length-1)%colors.length]}); | ||
+ | } | ||
+ | else { | ||
+ | b.board.create('sector', [cNode, firstNode, veryFirstNode], {strokeWidth:2, strokeColor:'black', opacity:1, fillColor:colors[(degrees.length-1)%colors.length]}); | ||
+ | } | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | piechart([400,250,225,125],{labels:['SA','NA','TE','HV'],percentLabels:true,phantomText:'heja',colors:[mlg.tikzColor('mlhoy!60'),mlg.tikzColor('mltiny!60'),mlg.tikzColor('mlhank!60'),mlg.tikzColor('mlmary!60'),]}); | ||
</jsxgpre> | </jsxgpre> | ||
+ | |||
+ | |||
[[Kategori:Cirkeldiagram]] | [[Kategori:Cirkeldiagram]] |