How to graphically represent a percentage in this way?

Hi

The client wants a percentage (that will be returned from my php code) to be represented like this:

Untitled-1

Ive been looking at Google Charts but cant find a way to represent a percentage as this. (I dont even know if this chart type actually has a name?).

Does anyone know how I could achieve this?

Thanks

Hmmm, interesting.

Will you always have 18 people and have to color what percentage is returned from your PHP script? E.g. If it returns 50% you have to color 9 people red and leave 9 people white.

Or will you have x/y people. So maybe your PHP script returns “15/18” and you are expected to draw 18 people and color 15 red?

1 Like

The type of chart that’s wanted is commonly called a Pictogram Chart.

3 Likes

The number of people will always be 18. The idea is to display the infographic with text reading something like “People of your age have 10% chance of developing disease”.

This raises an interesting point - in this example is it possible to have 1.8 people coloured in!? Perhaps thats a step too far! :slight_smile: Just having whole people coloured in for now will suffice.

If it’s coming from PHP, that could probably do the work.
First the number crunching to work out how many out of 18 (or whatever number) should be filled.
Then simply add a class to so many SVG objects to fill them red.

Anything is possible, but that’s making it harder.
It would be easier to use 10 or 20 people, but rouding isn’t a problem if you stick with rounding to the nearset one.

1 Like

Here’s a good example of using d3.js to show a pictogram chart.

1 Like

Fantastic - this will do the job.

Ive spent the morning reading Google Charts documentation which all looks really good but doesnt seem to handle pictograms (I may be wrong). This is all new territory for me. In a few hours Ive learnt a lot about how to display statistical information!

D3 seems to be an alternative of Google Charts?

Since I’m hopeless with js and the data is coming from PHP anyway, I thought I would have a go at a PHP solution. It should be OK if you are working with set statistics. If you need to numbers to be altered by the user on-page like the example, you will of course need js.

<?php
	function percent(float $percent, int $people = 18){
		return round($percent / 100 * $people) ;
	}
	
	$people = 18; 	// How many icons to display
	$percent = 43.6;	// Percentage statistic
	
	$filled = percent($percent, $people); // Get number of icons to fill
?>
<!DOCTYPE html>
<html>
    <head>
		<meta charset="UTF-8">
		<meta name=viewport content="width=device-width, initial-scale=1">
		<title>Pictogram</title>
		<style>
			.hide { display: none;}
			.chart {
				background: #fa0;
				padding: 1em;
				max-width: 30em;
				margin: 1em auto;
				display: flex;
				flex-wrap: wrap;
				justify-content: space-around;
				text-align: center;
				font-family: sans-serif;
			}
			.icon {
				fill: #fff;
				stroke: #f00;
				stroke-width: 2px;
				width: 5em;
				height: auto;
				margin-bottom: 0.6em;
			}
			.filled {
				fill: #f00;
			}
		</style>
	</head>
	<body>
		<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="hide">
			<defs>
				<g id="man">
					<path d="M46.004,21.672c5.975,0,10.836-4.861,10.836-10.836S51.979,0,46.004,0c-5.975,0-10.835,4.861-10.835,10.836 S40.029,21.672,46.004,21.672z"/>
					<path d="M68.074,54.008L59.296,26.81c-0.47-1.456-2.036-2.596-3.566-2.596h-1.312H53.48H38.526h-0.938h-1.312
					c-1.53,0-3.096,1.14-3.566,2.596l-8.776,27.198c-0.26,0.807-0.152,1.623,0.297,2.24s1.193,0.971,2.041,0.971h2.25
					c1.53,0,3.096-1.14,3.566-2.596l2.5-7.75v10.466v0.503v29.166c0,2.757,2.243,5,5,5h0.352c2.757,0,5-2.243,5-5V60.842h2.127v26.166
					c0,2.757,2.243,5,5,5h0.352c2.757,0,5-2.243,5-5V57.842v-0.503v-10.47l2.502,7.754c0.47,1.456,2.036,2.596,3.566,2.596h2.25
					c0.848,0,1.591-0.354,2.041-0.971S68.334,54.815,68.074,54.008z"/>
				</g>
			</defs>
		</svg>
		<figure class="chart">
			<?php
			for($n = 0; $n < $people; $n++) :
				$class = '';
				if($n < $filled){ $class = ' filled' ;}
			?>
			<svg class="icon<?= $class ?>" viewBox="5 -2 80 100">
				<use xlink:href="#man"></use>
			</svg>
			<?php endfor ?>
			<figcaption><?= $percent ?>% of People here don't know javascript.</figcaption>
		</figure>
		
	</body>
</html>
3 Likes

That’s a nice demo, Sam :slight_smile:

1 Like

Thanks @SamA74. Im getting “Fatal error: Default value for parameters with a class type hint can only be NULL” on the 1st line?

I don’t know much about PHP, but my impression from that error message is that the int isn’t required when giving default values, resulting in needing the following update:

	// function percent(float $percent, int $people = 18){
	function percent(float $percent, $people = 18){

/me proceeds to google-search about class hinting in PHP

Class hinting in PHP is best used with objects and arrays. Strings and ints aren’t classes.

Great - thats now working.

Great job @SamA74 !!!

One of the problems with Pictograms is that they are very inaccurate, especially when the number of blocks is small. As an example, if you had 18 blocks (or men, if you prefer), and you wanted to represent 40% in your display, you get the following numbers:
40-41% is displayed as 38.88% of the total blocks (7/18)
42-47% is displayed as 44.44% (8/18)
48% is displayed as 50% (9/18).

If you want to play around with the results by varying the number of blocks or the percentage displayed, you might find this demo instructive. Fiddle

1 Like