August 27

BrandColors

Official color codes for the wolrd's biggest brand [...]

Official color codes for the wolrd's biggest brands

August 27

git - the simple guide

git - the simple guide

just a simple guide for getting started with git. no deep shit ;)

by Roger Dudler 
credits to @tfnico@fhd and Namics
this guide in deutschespañolfrançaisindonesianitalianonederlandspolskiportuguêsрусскийtürkçe
မြန်မာ日本語中文한국어 Vietnamese 
please report issues on github

Frontify - Collaboration for Web Designers & Front-End Developers

create a new repository

create a new directory, open it and perform a 
git init
to create a new git repository.

checkout a repository

create a working copy of a local repository by running the command
git clone /path/to/repository
when using a remote server, your command will be
git clone username@host:/path/to/repository

workflow

your local repository consists of three "trees" maintained by git. the first one is your Working Directory which holds the actual files. the second one is the Index which acts as a staging area and finally theHEAD which points to the last commit you've made.

add & commit

You can propose changes (add it to the Index) using
git add
git add *
This is the first step in the basic git workflow. To actually commit these changes use
git commit -m "Commit message"
Now the file is committed to the HEAD, but not in your remote repository yet.

pushing changes

Your changes are now in the HEAD of your local working copy. To send those changes to your remote repository, execute 
git push origin master
Change master to whatever branch you want to push your changes to. 

If you have not cloned an existing repository and want to connect your repository to a remote server, you need to add it with
git remote add origin
Now you are able to push your changes to the selected remote server

branching

Branches are used to develop features isolated from each other. Themaster branch is the "default" branch when you create a repository. Use other branches for development and merge them back to the master branch upon completion.

create a new branch named "feature_x" and switch to it using
git checkout -b feature_x
switch back to master
git checkout master
and delete the branch again
git branch -d feature_x
a branch is not available to others unless you push the branch to your remote repository
git push origin

update & merge

to update your local repository to the newest commit, execute 
git pull
in your working directory to fetch and merge remote changes.
to merge another branch into your active branch (e.g. master), use
git merge
in both cases git tries to auto-merge changes. Unfortunately, this is not always possible and results in conflicts. You are responsible to merge those conflicts manually by editing the files shown by git. After changing, you need to mark them as merged with
git add
before merging changes, you can also preview them by using
git diff

tagging

it's recommended to create tags for software releases. this is a known concept, which also exists in SVN. You can create a new tag named 1.0.0by executing
git tag 1.0.0 1b2e1d63ff
the 1b2e1d63ff stands for the first 10 characters of the commit id you want to reference with your tag. You can get the commit id by looking at the... 

log

in its simplest form, you can study repository history using.. git log
You can add a lot of parameters to make the log look like what you want. To see only the commits of a certain author:
git log --author=bob
To see a very compressed log where each commit is one line:
git log --pretty=oneline
Or maybe you want to see an ASCII art tree of all the branches, decorated with the names of tags and branches: 
git log --graph --oneline --decorate --all
See only which files have changed: 
git log --name-status
These are just a few of the possible parameters you can use. For more, see git log --help

replace local changes

In case you did something wrong, which for sure never happens ;), you can replace local changes using the command
git checkout --
this replaces the changes in your working tree with the last content in HEAD. Changes already added to the index, as well as new files, will be kept.

If you instead want to drop all your local changes and commits, fetch the latest history from the server and point your local master branch at it like this
git fetch origin
git reset --hard origin/master

useful hints

built-in git GUI
gitk
use colorful git output
git config color.ui true
show log on just one line per commit
git config format.pretty oneline
use interactive adding
git add -i

August 27

PHP Spinner Updated - Spin articles for SEO

A Collection Of Thoughts

Location: Home

PHP Spinner Updated - Spin articles for SEO

Quite a while ago I wrote a post on spinning text using PHP to create lots of fresh content from one single block of marked up text. I actually had use for a nested version of this spinning code the other day so set about creating a more efficient version of my previous nested spin code and packed it up in a class wrapper so it would choose whether to use the nested spinner or the flat version dynamically.

Without further ado here is the new PHP Spinner code.

class Spinner
{
	# Detects whether to use the nested or flat version of the spinner (costs some speed)
	public static function detect($text $seedPageName = true $openingConstruct = '{{' $closingConstruct = '}}' $separator = '|')
	{
		if(preg_match('~'$openingConstruct'(?:(?!'$closingConstruct').)*'$openingConstruct'~s' $text))
		{
			return self::nested($text $seedPageName $openingConstruct $closingConstruct $separator);
		}
		else
		{
			return self::flat($text $seedPageName false $openingConstruct $closingConstruct $separator);
		}
	}
 
	# The flat version does not allow nested spin blocks, but is much faster (~2x)
	public static function flat($text $seedPageName = true $calculate = false $openingConstruct = '{{' $closingConstruct = '}}' $separator = '|')
	{
		# Choose whether to return the string or the number of permutations
		$return = 'text';
		if($calculate)
		{
			$permutations	= 1;
			$return			= 'permutations';
		}
 
		# If we have nothing to spin just exit (don't use a regexp)
		if(strpos($text $openingConstruct) === false)
		{
			return $$return;
		}
 
		if(preg_match_all('!'$openingConstruct'(.*?)'$closingConstruct'!s' $text $matches))
		{
			# Optional, always show a particular combination on the page
			self::checkSeed($seedPageName);
 
			$find		= array();
			$replace	= array();
 
			foreach($matches as $key => $match)
			{
				$choices = explode($separator $matches1$key);
 
				if($calculate)
				{
					$permutations *= count($choices);
				}
				else
				{
					$find		= $match;
					$replace	= $choicesmt_rand( count($choices) - 1);
				}
			}
 
			if($calculate)
			{
				# Ensure multiple instances of the same spinning combinations will spin differently
				$text = self::str_replace_first($find $replace $text);
			}
		}
 
		return $$return;
	}
 
	# The nested version allows nested spin blocks, but is slower
	public static function nested($text $seedPageName = true $openingConstruct = '{{' $closingConstruct = '}}' $separator = '|')
	{
		# If we have nothing to spin just exit (don't use a regexp)
		if(strpos($text $openingConstruct) === false)
		{
			return $text;
		}
 
		# Find the first whole match
		if(preg_match('!'$openingConstruct'(.+?)'$closingConstruct'!s' $text $matches))
		{
			# Optional, always show a particular combination on the page
			self::checkSeed($seedPageName);
 
			# Only take the last block
			if(($pos = mb_strrpos($matches1 $openingConstruct)) !== false)
			{
				$matches1 = mb_substr($matches1 $pos + mb_strlen($openingConstruct));
			}
 
			# And spin it
			$parts	= explode($separator $matches1);
			$text	= self::str_replace_first($openingConstruct$matches1$closingConstruct $partsmt_rand( count($parts) - 1) $text);
 
			# We need to continue until there is nothing left to spin
			return self::nested($text $seedPageName $openingConstruct $closingConstruct $separator);
		}
		else
		{
			# If we have nothing to spin just exit
			return $text;
		}
	}
 
	# Similar to str_replace, but only replaces the first instance of the needle
	private static function str_replace_first($find $replace $string)
	{
		# Ensure we are dealing with arrays
		if(is_array($find))
		{
			$find = array($find);
		}
 
		if(is_array($replace))
		{
			$replace = array($replace);
		}
 
		foreach($find as $key => $value)
		{
			if(empty($value))
			{
				if(($pos = mb_strpos($string $value)) !== false)
				{
					# If we have no replacement make it empty
					if(isset($replace$key))
					{
						$replace$key = '';
					}
 
					$string = mb_substr($string  $pos)$replace$keymb_substr($string $pos + mb_strlen($value));
				}
			}
		}
 
		return $string;
	}
 
	private static function checkSeed($seedPageName)
	{
		# Don't do the check if we are using random seeds
		if($seedPageName)
		{
			if($seedPageName === true)
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'));
			}
			elseif($seedPageName == 'every second')
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'date('Y-m-d-H-i-s')));
			}
			elseif($seedPageName == 'every minute')
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'date('Y-m-d-H-i')));
			}
			elseif($seedPageName == 'hourly' OR $seedPageName == 'every hour')
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'date('Y-m-d-H')));
			}
			elseif($seedPageName == 'daily' OR $seedPageName == 'every day')
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'date('Y-m-d')));
			}
			elseif($seedPageName == 'weekly' OR $seedPageName == 'every week')
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'date('Y-W')));
			}
			elseif($seedPageName == 'monthly' OR $seedPageName == 'every month')
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'date('Y-m')));
			}
			elseif($seedPageName == 'annually' OR $seedPageName == 'every year')
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'date('Y')));
			}
			elseif(preg_match('!every ([0-9.]+) seconds!' $seedPageName $matches))
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'floor(time() / $matches1)));
			}
			elseif(preg_match('!every ([0-9.]+) minutes!' $seedPageName $matches))
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'floor(time() / ($matches1 * 60))));
			}
			elseif(preg_match('!every ([0-9.]+) hours!' $seedPageName $matches))
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'floor(time() / ($matches1 * 3600))));
			}
			elseif(preg_match('!every ([0-9.]+) days!' $seedPageName $matches))
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'floor(time() / ($matches1 * 86400))));
			}
			elseif(preg_match('!every ([0-9.]+) weeks!' $seedPageName $matches))
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'floor(time() / ($matches1 * 604800))));
			}
			elseif(preg_match('!every ([0-9.]+) months!' $seedPageName $matches))
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'floor(time() / ($matches1 * 2620800))));
			}
			elseif(preg_match('!every ([0-9.]+) years!' $seedPageName $matches))
			{
				mt_srand(crc32($_SERVER'REQUEST_URI'floor(time() / ($matches1 * 31449600))));
			}
			else
			{
				throw new Exception($seedPageName ' Was not a valid spin time option!');
			}
		}
	}
}

And an example:

$string = '{{The|A}} {{quick|speedy|fast}} {{brown|black|red}} {{fox|wolf}} {{jumped|bounded|hopped|skipped}} over the {{lazy|tired}} {{dog|hound}}';
 
echo '

';   for($i = 1; $i <= 5; $i++) { echo Spinner::detect($string false)'
'
; // or Spinner::flat($string, false).'
';
}   echo '

'
;

Which produces:

The speedy black wolf bounded over the lazy hound
A speedy brown fox skipped over the tired hound
The quick red wolf bounded over the lazy hound
The fast brown fox hopped over the tired dog
The speedy brown fox jumped over the tired dog

and it will work happily as a nested PHP spinner too:

$string = '{{A {{simple|basic}} example|An uncomplicated scenario|The {{simplest|trivial|fundamental|rudimentary}} case|My {{test|invest{{igative|igation}}}} case}} to illustrate the {{function|problem}}';
 
echo '

';   for($i = 1; $i <= 5; $i++) { echo Spinner::detect($string false)'
'
; // or Spinner::nested($string, false).'
';
}   echo '

'
;

Which produces:

A basic example to illustrate the function
My test case to illustrate the problem
The rudimentary case to illustrate the function
An uncomplicated scenario to illustrate the problem
The fundamental case to illustrate the problem

Improvement

The spinner now allows seed page options to be strings such as 'daily', 'every 2.5 hours' or 'every 3 weeks' rather than just true / false so the spun text will automatically update every set period of time. See the checkSeed (bottom) function for allowed values.

Have fun spinning articles! Any comments, suggestions or improvements are welcome.

all content ©2009-2016 Paul Norman
August 27

Peity Javascript Graphs

Peity

 

Peity (sounds like deity) is a simple jQuery plugin that converts an element's content into a simple  mini pie  donut  line  or bar chart  and is compatible with any browser that supports : Chrome, Firefox, IE9+, Opera, Safari.

Download version 3.2.0

Uncompressed 8.7Kb
jquery.peity.js
Minified 3.6Kb (+gzipped 1.7Kb)
jquery.peity.min.js
Source
github.com/benpickles/peity

Fork me on GitHub

Pie Charts

Simply call peity("pie") on a jQuery selection. There are two subtly different pie chart semantics, a "/" delimiter is assumed to mean "three out of five" and only the first two values will be drawn, otherwise all of the values are included in the chart and the total is the sum of all values.

You can also pass delimiterfillheightradius and width options. Passing a radius will set the correct width and height, the pie will always be a circle that fits the available space.

      

HTML

1/5
226/360
0.52/1.561
1,4
226,134
0.52,1.041
1,2,3,2,2

JavaScript

$("span.pie").peity("pie")

Donut Charts

Donut charts are the same as pie charts and take the same options with an addedinnerRadius option which defaults to half the radius.

      

HTML

1/5
226/360
0.52/1.561
1,4
226,134
0.52,1.041
1,2,3,2,2

JavaScript

$('.donut').peity('donut')

Line Charts

Line charts work on a comma-separated list of digits. Line charts can take the following options: delimiterfillheightmaxminstrokestrokeWidth andwidth.

  

HTML

5,3,9,6,5,9,7,3,5,2
5,3,2,-1,-3,-2,2,3,5,2
0,-3,-6,-4,-5,-4,-7,-3,-5,-2

JavaScript

$(".line").peity("line")

Bar Charts

Bar charts work in the same way as line charts and take the following options:delimiterfillheightmaxminpadding and width.

  

HTML

5,3,9,6,5,9,7,3,5,2
5,3,2,-1,-3,-2,2,3,5,2
0,-3,-6,-4,-5,-4,-7,-3,-5,-2

JavaScript

$(".bar").peity("bar")

data-* attributes

Data attributes can be used to pass custom settings per-chart - options explicitly passed to the peity() function take precedence over data-* attributes.

      

HTML

1/7 2/7 3/7 4/7 5/7 6/7 7/7

JavaScript

$(".data-attributes span").peity("donut")

Setting Colours Dynamically

Pie, donut and bar chart colours can be defined dynamically based on the values of the chart. When passing an array its values are cycled, when passing a function it is called once for each value allowing you to define each bar or segment's colour. The callback is invoked with the value, its index, and the full array of values - the same arguments as the callback for Array#forEach.

    

HTML

5,3,9,6,5,9,7,3,5,2
5,3,2,-1,-3,-2,2,3,5,2
0,-3,-6,-4,-5,-4,-7,-3,-5,-2
4,7,6,5
5,3,9,6,5

JavaScript

$(".bar-colours-1").peity("bar", {
  fill: ["red", "green", "blue"]
})

$(".bar-colours-2").peity("bar", {
  fill: function(value) {
    return value > 0 ? "green" : "red"
  }
})

$(".bar-colours-3").peity("bar", {
  fill: function(_, i, all) {
    var g = parseInt((i / all.length) * 255)
    return "rgb(255, " + g + ", 0)"
  }
})

$(".pie-colours-1").peity("pie", {
  fill: ["cyan", "magenta", "yellow", "black"]
})

$(".pie-colours-2").peity("pie", {
  fill: function(_, i, all) {
    var g = parseInt((i / all.length) * 255)
    return "rgb(255, " + g + ", 0)"
  }
})

Updating Charts

Charts can be updated by changing the the jQuery selection's text content and callingchange() on it. The chart will be redrawn with the same options that were originally passed to it.

HTML

5,3,9,6,5,9,7,3,5,2,5,3,9,6,5,9,7,3,5,2

JavaScript

var updatingChart = $(".updating-chart").peity("line", { width: 64 })

setInterval(function() {
  var random = Math.round(Math.random() * 10)
  var values = updatingChart.text().split(",")
  values.shift()
  values.push(random)

  updatingChart
    .text(values.join(","))
    .change()
}, 1000)

Custom Charts

You can add a custom chart type by registering it with Peity with a name, defaults object, and custom chart drawing function which is called with an options object. See the existing charts for examples.

$.fn.peity.register('custom', {
    option: defaults
  }, function(opts) {
    // Implementation.
  }
)

Events

Peity adds a "change" event trigger to your graph elements, so if you update their data your can regenerate one or more charts by triggering change() on them.

  •  
  •  
  •  

Chart updated: 3/5

HTML

Nothing's happened yet.

JavaScript

$('select').change(function() {
  var text = $(this).val() + '/' + 5

  $(this)
    .siblings('span.graph')
    .text(text)
    .change()

  $('#notice').text('Chart updated: ' + text)
}).change()

$('span.graph').peity('pie')

Default Settings

Defaults can be overridden globally like so:

$.fn.peity.defaults.pie = {
  delimiter: null,
  fill: ["#ff9900", "#fff4dd", "#ffd592"],
  height: null,
  radius: 8,
  width: null
}

$.fn.peity.defaults.donut = {
  delimiter: null,
  fill: ["#ff9900", "#fff4dd", "#ffd592"],
  height: null,
  innerRadius: null,
  radius: 8,
  width: null
}

$.fn.peity.defaults.line = {
  delimiter: ",",
  fill: "#c6d9fd",
  height: 16,
  max: null,
  min: 0,
  stroke: "#4d89f9",
  strokeWidth: 1,
  width: 32
}

$.fn.peity.defaults.bar = {
  delimiter: ",",
  fill: ["#4d89f9"],
  height: 16,
  max: null,
  min: 0,
  padding: 0.1,
  width: 32
}

CHANGELOG

Version 3.2.0 - 2015/4/17

  • Add an after hook that can be used to decorate a chart.
August 27

Chartlets: Tiny charts for tablet and mobile web apps

Chartlets: Tiny charts for tablet and mobile web a [...]

Chartlets

(Tiny charts for tablet and mobile web apps.)

Line charts

Bar charts

Pie charts

Custom charts

Docs

What are Chartlets?

Chartlets are tiny charts without grids or legends, like Sparklines. They're perfect for conveying simple relationships or trends, especially when space is scarce.

Chartlets uses the HTML5 element for fast performance and is only 2.8k when minified and gzipped. It has no dependencies.

Usage

1. Download and include .

2. Create a element with a width, height, and the class name "chartlet." Then add HTML5 data attributes as described below.

3. Call Chartlets.render().

Examples

Chart Types

Chartlets includes three basic chart types:

data-type="line" ...>

data-type="bar" ...>

data-type="pie" ...>

Chart Data

Data is expressed as one or more sets of y-values, depending on the chart type. Sets must be of equal length; x-scales are assumed to have even increments.

data-sets="[1 2 3 4 5] [5 4 3 2 1]">

data-sets="[1.5 2.5 3.5] [4.5 5.5 6.5]">

data-sets="[10 20 30]">


Scales are derived from the minimum and maximum data points unless explicited stated:

data-range="0 10" data-sets="[1 3 5] [2 4 6]">


Pro tip: Data can be expressed in shorthand notation (e.g. "[1 2] [3 4]") or JSON (e.g. "[[1, 2], [3, 4]]").

Chart Colors

Colors are expressed in hexadecimal, RGB(A) or HSL(A) notation, one color for each data set.

data-colors="#f00 #bada55">

data-colors="rgb(255,0,0) rgba(10,20,30,0.5)">

data-colors="hsl(200, 83%, 50%) hsla(319, 83%, 50%, 0.5)">

Themes

Instead of specifying an array of colors, you can apply a color theme:

data-opts="theme:money">

Pick from one of ten built-in themes, each with five colors:

Or create a custom theme using any number and combination of hex, RGB(A) or HSL(A) strings:

Chartlets.setTheme("rainbow", ["#eb1f1f", "#fcb13a", "#ffd026"]);

To load the current color set:

var colors = Chartlets.getTheme();

Or to load colors for a particular theme:

var colors = Chartlets.getTheme("money");

Chart Options

Chartlets can be customized via the data-opts attribute:

data-opts="stroke:2 shape:smooth cap:circle">

Global options

  • bgcolor sets the background color of the entire chart. It can be in hex, RGB(A) or HSL(A) notation. The background is transparent by default.

  • theme sets the color theme for the chart data, overriding any colors specified in data-colors. If no theme is specified and data-colors is empty, the "blues" theme is applied.

Line options

  • stroke sets the line width, a value between 1 and 3, inclusive. The default value is 1.

  • shape sets the line contour. Acceptable values are straight, smooth and step. The default value is straight.

  • cap renders an icon at each data point. Acceptable values are none, circle and square. The default value is none.

  • fill sets the fill style, either none or solid. The default value is none.

  • alpha sets the opacity of the fill, a number between 0 and 1.0, inclusive. The default value is 0.5 (or 1.0 if transform is set to stack).

  • transform specifies how to structure the data sets. Acceptable values are none and stack. If stack, data sets are "stacked" bottom to top. The default value is none.

  • axis renders a dashed line at the given y-value.

Bar options

  • orient sets the orientation of the chart, either horiz or vert. The default value is vert.

  • transform specifies how to structure the data sets. Acceptable values are none and stack. If stack, data sets are "stacked" bottom to top. The default value is none.

  • axis renders an axis line at the given y-value.

Updating Data

The update method helps you re-render charts with new data (or populate charts with data from an AJAX request). It accepts an element (or element ID) and an array of data sets. Below, the element with ID "demo1" is updated with new values every 500ms.

var a = [2, 3, 5, 3, 6, 3, 7, 8, 4, 2];
var b = [8, 3, 4, 7, 2, 7, 2, 4, 6, 1];

setInterval(function() {
  a.push(Math.ceil(Math.random() * 9));
  b.push(Math.ceil(Math.random() * 9));
  a.shift();
  b.shift();

  Chartlets.update("demo1", [a, b]);
}, 500);

Here, a pie chart acts as a progress meter:

var a = 0;

setInterval(function() {
  if (++a > 100) {
    a = 0;
  }

  Chartlets.update("demo2", [[a, 100 - a]]);
}, 50);

Transitions

You can apply a transition effect during an update if the old and new data structures are identical. For example:

Chartlets.update("my-chart-id", [[1,2,3], [4,5,6]], { transition: "linear" });

The only transition type is "linear." Try it out below:

Custom Chart Types

You can create your own chart type by writing a custom renderer. For example, say you want to draw a smiley face with a configurable smile:

The setRenderer method accepts a chart type and rendering function, which gives you direct access to the canvas context, chart data and other properties:

Chartlets.setRenderer("smiley", function (ctx, width, height, sets, opts) {
  // width = 75
  // height = 75
  // sets = [[1,2], [3,4]]
  // opts = { gender: "male", hair: "yes" }
  // colors = Chartlets.getTheme()

  // now draw into ctx
});

Transitions should work without any additional logic. Following on the above example, a smiley face might transition from a smile to a frown when the chart is updated:

Chartlets.update("smiley1", [[4,3], [2,1]], { transition: "linear" });

Notes

August 27

Harry Plotter

harry is a lightweight standalone javascript library to plot data as charts, pies, donuts, lines or curves