randFromArray([ [new Plural(function(num) { return $.ngettext("animal", "animals", num); }), KhanUtil.animal], [new Plural(function(num) { return $.ngettext("color", "colors", num); }), KhanUtil.color], [new Plural(function(num) { return $.ngettext("fruit", "fruits", num); }), KhanUtil.fruit], [new Plural(function(num) { return $.ngettext("course", "courses", num); }), KhanUtil.course] ]) _.times(5, function(n) { return SUBJECT_FUNC(n + 1); } ) _.times(5, function() { return randRange(0, 10); } ) sum(DATA) randFromArray([ new Plural(function(num) { return $.ngettext("student", "students", num); }), new Plural(function(num) { return $.ngettext("teacher", "teachers", num); }), new Plural(function(num) { return $.ngettext("person", "people", num); }) ]) shuffle(_.zip(DATA, CATEGORIES))

`TOTAL` RESPONDENT was asked about their favorite SUBJECT. `TOTAL` plural_form(RESPONDENT, TOTAL) were asked about their favorite SUBJECT. `DATA[0]` RESPONDENT said DATA[1]. `DATA[0]` plural_form(RESPONDENT, DATA[0]) said DATA[1].

Create a bar chart showing everyone's favorite plural_form(SUBJECT):

init({ range: [ [ -2, 17 ], [ -3, 12 ] ], scale: [ 26, 30 ] }); addMouseLayer(); for ( var y = 0; y <= 10; ++y ) { label( [ 0, y ], y, "left", false ); style({ stroke: "#000", strokeWidth: 1, opacity: 0.3 }, function() { line( [ 0, y ], [ 16, y ] ) }); } graph.leftPoints = []; graph.rightPoints = []; graph.lines = []; for ( var index = 0; index < CATEGORIES.length; ++index ) { graph.leftPoints[ index ] = addMovablePoint({ coord: [ index * 3 + 1, 0.5 ], visible: false }); graph.rightPoints[ index ] = addMovablePoint({ coord: [ index * 3 + 3, 0.5 ], visible: false }); graph.lines[ index ] = addMovableLineSegment({ pointA: graph.leftPoints[ index ], pointZ: graph.rightPoints[ index ], snapY: 0.5, constraints: { constrainX: true } }); // graph.lines[ index ] = {}; style({ stroke: "none", fill: "#9ab8ed", opacity: 1.0 }, function() { graph.lines[ index ].bar = path([ [ index * 3 + 1, 0 ], [ index * 3 + 1, 0.5 ], [ index * 3 + 3, 0.5 ], [ index * 3 + 3, 0 ], [ index * 3 + 1, 0 ] ]); }); // graph.lines[ index ].toFront(); label( [ index * 3 + 2, 0 ], CATEGORIES[ index ] + "", "below", false ).css( "text-transform", "capitalize" ); var bar = index; graph.lines[ index ].onMove = function( dX, dY ) { if ( this.coordA[1] < 0 || this.coordA[1] > 10 ) { this.coordA[1] -= dY; this.coordZ[1] -= dY; } this.pointA.setCoord([ this.pointA.coord[0], this.coordA[1] ]); this.pointZ.setCoord([ this.pointZ.coord[0], this.coordA[1] ]); this.pointA.updateLineEnds(); this.pointZ.updateLineEnds(); this.bar.scale( 1, Math.max( 0.01, this.coordA[1] * 2 ), scalePoint( 0 )[0], scalePoint( 0 )[1] ); }; } style({ stroke: "#000", strokeWidth: 2, opacity: 1.0 }, function() { line( [ 0, 0 ], [ 16, 0 ] ); line( [ 0, 0 ], [ 0, 10 ] ); }); label([8, -0.8], SUBJECT + "", "below", false) .css("text-transform", "capitalize") .css("font-weight", "bold"); label([-1.5, 5], $._("Number of %(respondent)s", { respondent: plural_form(RESPONDENT) }), "center", false) .css("font-weight", "bold") .addClass("rotate"); label([8, 10.5], $._("Favorite %(subject)s", { subject: plural_form(SUBJECT) }), "above", false) .css("font-weight", "bold");
_.times(5, function(n) { return graph.lines[ n ].coordA[1]; })
if ( _.isEqual( guess, [ 0.5, 0.5, 0.5, 0.5, 0.5 ] ) ) { return ""; } return _.isEqual( guess, DATA );
$.each( guess, function( index ) { graph.lines[ index ].pointA.setCoord([ graph.lines[ index ].pointA.coord[0], this ]); graph.lines[ index ].pointZ.setCoord([ graph.lines[ index ].pointZ.coord[0], this ]); graph.lines[ index ].pointA.updateLineEnds(); graph.lines[ index ].pointZ.updateLineEnds(); graph.lines[ index ].bar.scale( 1, Math.max( 0.01, this * 2 ), scalePoint( 0 )[0], scalePoint( 0 )[1] ); });

`NUM` RESPONDENT said their favorite SUBJECT was CATEGORIES[ INDEX ]. `NUM` plural_form(RESPONDENT, NUM) said their favorite SUBJECT was CATEGORIES[ INDEX ]. So the top of the bar for "CATEGORIES[ INDEX ]" should line up with the number `NUM` on the left side of the chart. So there should be no bar above "CATEGORIES[ INDEX ]". Drag the top of the bar all the way to the bottom to get rid of the bar.

style({ stroke: ORANGE, fill: "none", strokeWidth: 1, strokeDasharray: "- " }, function() { path([ [ INDEX * 3 + 1, 0 ], [ INDEX * 3 + 1, NUM ], [ INDEX * 3 + 3, NUM ], [ INDEX * 3 + 3, 0 ] ]).toBack(); });