Half-Elf on Tech

Thoughts From a Professional Lesbian

Tag: chart

  • What Is The Measure of a Site?

    What Is The Measure of a Site?

    After you think about where you’re saving your data, internally or externally, you’re going to be faced with the biggest problem known to exist.

    What do you do with your data?

    Common Data is (Mostly) Obvious

    Some data, as I’ve said before, is obvious. That is, you know what you want to do with statistics of visits. The base outset is ‘figure out how many people visit my site.’ Right? Not too hard. But that isn’t all you want to know. You want to know when your site is busiest, what content people read, and maybe you want to know on what device.

    You want to know these things because they can help you optimize what you do next. If, for example, your Monday posts are super popular, then you want to make sure you post them at the time the most people are going to visit your site. If you know only 2 people view your site on an iPad, maybe fixing that little annoyance can wait a bit.

    Rare Data is A Headache

    On the other hand, when you look at statistics for your complex data, like a site with TV shows and characters and actors, you have a completely different problem. What public stats are both relevant and meaningful? And how do you represent them in ways that people can understand?

    Like, do you use piecharts?

    An example of two pie charts

    They can be helpful but only if you don’t have a large number of data slices.

    I made a pie chart with 28 slices and it was unreadable. Though that was mostly because everyone had between 1-5% except for one that had 75%.

    The Question Is Usage

    This is a problematic question because it has no easily defined answer before you start building out your site. We’ve all seen an image of a paved path and then a foot-trail cutting away from it, or winding around an obstacle. People like to joke about how it’s design vs usage. While our goal when making any product is to avoid people walking off the paths, it’s unavoidable. And in the case of public statistics, it’s even harder to predict usage.

    A large reason for the problem is what is called a failure of imagination. This is, in part, the fault of the designers. That is, they didn’t predict things properly. Which requires metrics. Which can’t be gathered until people have used the site a little.

    You see the problem, I hope.

    Start With The Easy

    When I built out stats on my site, the ones I wanted people to use, I made sure to start with some easy things. Like those pie charts. Those are just pulled from a custom taxonomy which every character has. They’re simple. They’re easy. And they let people visualize.

    After I released it, someone asked “Could we have a chart to show how many actors a character has?”

    Actors per Character

    That was actually not easy, but the point is that by starting with something ‘easy’ I was able to inspire people to ask what they wanted to see.

    Don’t Be Afraid to Be Wrong

    Remember I mentioned that evil pie chart? You’re going to be wrong. You’re going to assume that the best way to show a specific data point is a pie chart when it really should be a bar chart. If you pick the right chart systems, it shouldn’t be too horrible to switch between them. But sometimes it will be.

    Just remember, it’s okay to make mistakes. You can dig up a path and repave it after all.

  • Stacked Charts Part 3: The Javascript

    Stacked Charts Part 3: The Javascript

    Finally!

    We have our data in a properly consumable array. It’s formatted the way we need. Now we just need to script the java.

    Take a deep breath.

    What We Want

    What we want is simple. A stacked bar chart that shows the values of all possible permutations. It looks like this:

    A stacked chart that shows how many characters per gender orientation there are per country
    A stacked chart

    That shows how many characters there are per gender orientation, and stacks it for a total count (which is why we needed that count you see).

    Send In The Clowns

    Since I’m already using Chart.js, I just need to have a function to output the javascript. But. Since I also have to loop through the arrays to get the collective data, I need a bit of PHP:

    /*
     * Statistics Display Barcharts
     *
     * Output the list of data usually from functions like self::meta_array
     * It loops through the arrays and outputs data as needed
     *
     * This relies on ChartJS existing
     *
     * @param string $subject The content subject (shows, characters)
     * @param string $data The data - used to generate the URLs
     * @param array $array The array of data
     *
     * @return Content
     */
    static function stacked_barcharts( $subject, $data, $array ) {
    
    	// Defaults
    	$data       = ( $data == 'nations' )? 'nations' : substr( $data, 8 );
    	$title      = ucfirst( substr($subject, 0, -1) ) . ' ' . ucfirst( $data );
    	$height     = '550';
    
    	// Define our settings
    	switch ( $data ) {
    		case 'gender':
    		case 'sexuality':
    		case 'romantic':
    			$title    = 'Character per Nation by ' . ucfirst( $data );
    			$datasets = array();
    			$terms    = get_terms( 'lez_' . $data, array( 'orderby' => 'count', 'order' => 'DESC', 'hide_empty' => 0 ) );
    			if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
    				foreach ( $terms as $term ) $datasets[] = $term->slug;
    			}
    			$counter  = 'characters';
    			$height   = '400';
    			break;
    	}
    	?>
    	<h3><?php echo $title; ?></h3>
    	<div id="container" style="width: 100%;">
    		<canvas id="barStacked<?php echo ucfirst( $subject ) . ucfirst( $data ); ?>" width="700" height="<?php echo $height; ?>"></canvas>
    	</div>
    
    	<script>
    	// Defaults
    	Chart.defaults.global.responsive = true;
    	Chart.defaults.global.legend.display = false;
    
    	// Bar Chart
    	var barStacked<?php echo ucfirst( $subject ) . ucfirst( $data ); ?>Data = {
    		labels : [
    		<?php
    			foreach ( $array as $item ) {
    				if ( $item[$counter] !== 0 ) {
    					$name = esc_html( $item['name'] );
    				}
    				echo '"'. $name .' ('.$item[$counter].')", ';
    			}
    		?>
    		],
    		datasets: [
    		<?php
    		foreach ( $datasets as $label ) {
    			$color = ( $label == 'undefined' )? 'nundefined' : str_replace( ["-", "–","-"], "", $label );
    			?>
    			{
    				borderWidth: 1,
    				backgroundColor: window.chartColors.<?php echo $color; ?>,
    				label: '<?php echo ucfirst( $label ); ?>',
    				stack: 'Stack',
    				data : [<?php
    					foreach ( $array as $item ) {
    						echo $item[ 'dataset' ][ $label ] . ',';
    					}
    				?>],
    			},
    			<?php
    		}
    		?>
    		]
    	};
    	var ctx = document.getElementById("barStacked<?php echo ucfirst( $subject ) . ucfirst( $data ); ?>").getContext("2d");
    	var barStacked<?php echo ucfirst( $subject ) . ucfirst( $data ); ?> = new Chart(ctx, {
    		type: 'horizontalBar',
    		data: barStacked<?php echo ucfirst( $subject ) . ucfirst( $data ); ?>Data,
    		options: {
    			scales: {
    				xAxes: [{ stacked: true }],
    				yAxes: [{ stacked: true }]
    			},
    			tooltips: {
    				mode: 'index',
    				intersect: false
    			},
    		}
    	});
    
    	</script>
    	<?php
    }
    

    The Color

    You may have noticed a strange variable:

    $color = ( $label == 'undefined' )? 'nundefined' : str_replace( ["-", "–","-"], "", $label );
    

    Which was then called in the javascript here:

    backgroundColor: window.chartColors.<?php echo $color; ?>,
    

    I have this in a javascript file that is loaded on that page:

    // Color Defines
    window.chartColors = {
    	
    	// Gender
    	agender: 'rgba(255, 99, 132, 0.6)', // 'red'
    	cisgender: 'rgba(75, 192, 192, 0.6)', // 'aqua'
    	demigender: 'rgba(255, 205, 86, 0.6)', // 'goldenrod'
    	genderfluid: 'rgba(54, 162, 235, 0.6)', // 'light blue'
    	genderqueer: 'rgba(255, 159, 64, 0.6)', // 'orange'
    	nonbinary: 'rgba(201, 203, 207, 0.6)', // 'grey'
    	transman: 'rgba(0, 169, 80, 0.6)', // 'green'
    	transwoman: 'rgba(153, 102, 255, 0.6)', // 'purple'
    
    	// Sexuality
    	asexual: 'rgba(255, 99, 132, 0.6)', // 'red'
    	bisexual: 'rgba(75, 192, 192, 0.6)', // 'aqua'
    	heterosexual: 'rgba(255, 205, 86, 0.6)', // 'goldenrod'
    	homosexual: 'rgba(54, 162, 235, 0.6)', // 'light blue'
    	pansexual: 'rgba(255, 159, 64, 0.6)', // 'orange'
    	nundefined: 'rgba(201, 203, 207, 0.6)', // 'grey'
    	queer: 'rgba(0, 169, 80, 0.6)', // 'green'
    	demisexual: 'rgba(153, 102, 255, 0.6)', // 'purple'
    }
    

    The reason it’s ‘undefined’ is that things got weird when I had a variable with a name of undefined.