Make data dy­namic

Dis­cover the power of the Chart.js li­brary to cre­ate dy­namic charts and di­a­grams and make data more en­gag­ing

Web Designer - - Contents -

Em­ploy the power of the Chart.js li­brary to cre­ate dy­namic charts and di­a­grams to make data more en­gag­ing

In the­ory, cre­at­ing di­a­grams is not dif­fi­cult: han­dling the trigonom­e­try re­quired for a pie chart is among the most clas­sic jobs used for train­ing pro­gram­mers.

Rein­vent­ing the wheel ev­ery time an air­craft is to be built gets te­dious quickly – a lot of di­a­gram­ming li­braries vie for de­vel­oper’s at­ten­tion.

This story is based on Chart.js: the open-source prod­uct tops us­age statis­tics due to a unique trade-off be­tween ease of use and ad­vanced fea­tures. We will put the li­brary through its paces, cre­at­ing a set of print­able di­a­grams from ran­domly gen­er­ated data.

Thanks to the li­brary, eight dif­fer­ent chart types ap­pear in your web­sites with min­i­mal ef­fort. The re­cently-added an­i­ma­tions mod­ule en­riches the di­a­grams with snazzy-look­ing vi­su­als suited to amaze all but the most so­phis­ti­cated users.

In ad­di­tion to that, we will also risk a look across the pond by look­ing for­ward to learn­ing more about vi­su­al­i­sa­tion the­ory and al­ter­na­tive prod­ucts bet­ter suited to edge use cases.

1. De­ploy the li­brary

Due to the li­brary be­ing wide­spread, you can find its mini­fied ver­sion from var­i­ous CDNS such as Cloud­flare. Sim­ply load it with a <script> tag, and en­sure that a <can­vas> ob­ject is nearby – Chart.js does its magic by us­ing the ren­der­ing in­fra­struc­ture pro­vided in this wid­get. <html> <head>

<script src=”https://cd­njs .cloud­flare.com/ajax/libs/chart.js/2.4.0/ Chart.min.js”>

</script>

</head>

<body>

<can­vas id=”workarea”>

</can­vas>

</body> </html>

2. Start ini­tial­i­sa­tion

When the frame­work is loaded, the next step in­volves get­ting a Can­vas2d han­dle point­ing at the <can­vas> in­stance cre­ated in the pre­ced­ing step. This can then be used to cre­ate a new in­stance of the ‘Chart()’ class, which is re­spon­si­ble for data han­dling, ren­der­ing and in­ter­ac­tion.

<script> (func­tion() { var ctx = doc­u­ment. getele­ment­byid(‘workarea’).get­con­text(‘2d’); var chart = new Chart(ctx, {

type: ‘line’, op­tions: {}, . . . }); })(); </script>

3. Add a data source

Chart classes take a data pointer which pro­vides one or more ‘Dataset’ ob­jects con­tain­ing the ac­tual mea­sure­ment in­for­ma­tion. In the case of our line chart, only one Dataset is needed. It comes with the oblig­a­tory data el­e­ment and a few op­tional pa­ram­e­ters gov­ern­ing the ac­tual dis­play process. var chart = new Chart(ctx, { type: 'line', op­tions: {}, data: { la­bels: ["Jan­uary",

"Fe­bru­ary", "March", "April", "May", "June",

"July"], datasets: [{ la­bel: "My First dataset", back­ground­color: 'rgb(255, 99, 132)', bor­der­color: 'rgb(255, 99, 132)', data: [0, 10, 5, 2, 20, 30, 45], }] }

});

4. Stop flick­er­ing

Chart.js comes with so­phis­ti­cated re­siz­ing logic, which – un­for­tu­nately – tends to get screen sizes wrong from time to time. Lim­it­ing the size of the <can­vas> el­e­ment via CSS, sadly, does not do the trick. In­stead, both as­pect ra­tio main­te­nance and re­spon­siv­ity must be dis­abled via the op­tions field ac­com­pa­ny­ing the Chart classes con­struc­tor.

<can­vas id="workarea" style="width:800px; height:600px;"></can­vas></can­vas>

<script> (func­tion() { var ctx = doc­u­ment. getele­ment­byid('workarea').get­con­text('2d'); var chart = new Chart(ctx, {

type: 'line', op­tions: { re­spon­sive: false,main­tainaspec­tra­tio: false},

5. Add lay­outs…

To para­phrase An­drey Tupolev: now that the small one is fly­ing, let us bring up the big­ger one. The scaf­fold­ing shown ac­com­pa­ny­ing this step ‘mul­ti­plies’ our di­a­gram – in­stead of work­ing with one Can­vas el­e­ment, we now cre­ate a to­tal of four of them and ar­range them on the screen in a fash­ion sim­i­lar to a Le­croy os­cil­lo­scope. Sadly, this does not quite work out as in­tended.

<can­vas id="workarea" style="po­si­tion:ab­so­lute; top:0%; left: 0%; width:49%; height:49%;"></can­vas></can­vas> <can­vas id="workarea2" style="po­si­tion:ab­so­lute; top:0%; left: 51%; width:49%; height:49%;"></can­vas></can­vas> <can­vas id="workarea3" style="po­si­tion:ab­so­lute; top:51%; left: 0%; width:49%; height:49%;"></can­vas></can­vas> <can­vas id="workarea4" style="po­si­tion:ab­so­lute; top:51%; left: 51%; width:49%; height:49%;"></can­vas></can­vas>

6. … And tame ren­der­ing er­rors

The safest way to han­dle Chart.js di­a­grams in com­plex lay­outs in­volves us­ing wrap­per <div> tags. They en­force a struc­ture from the out­side, thereby en­sur­ing that the

in­ter­nal lay­out en­gine can not do more harm than nec­es­sary. In this case, how­ever, en­sure to re-en­able the re­spon­siv­ity fea­ture.

<div style="po­si­tion:ab­so­lute; top:0%; left:

0%; width:49%; height:49%;">

<can­vas id="workarea" ></can­vas></ can­vas>

</div>

<div style="po­si­tion:ab­so­lute; top:0%; left:

51%; width:49%; height:49%;">

<can­vas id="workarea2"></can­vas></ can­vas>

</div>

<div style="po­si­tion:ab­so­lute; top:51%; left: 0%; width:49%; height:49%;">

<can­vas id="workarea3" ></can­vas></ can­vas>

</div>

<div style="po­si­tion:ab­so­lute; top:51%; left: 51%; width:49%; height:49%;">

<can­vas id="workarea4" ></can­vas></ can­vas> </div> <script> doc­u­ment.ad­de­ventlis­tener("dom­con­tentl oaded", func­tion(){ var ctx = doc­u­ment. getele­ment­byid('workarea').get­con­text('2d'); var chart = new Chart(ctx, {

type: 'line', op­tions: { },

7. bars are fun

Al­ways ren­der­ing line charts gets te­dious quickly. Let’s spruce things up by chang­ing the type prop­erty to bar, thereby yield­ing bar di­a­grams such as the one shown in the fig­ure ac­com­pa­ny­ing this step. We pro­mote the data field to ‘global’ scope in order to elim­i­nate re­use. <script> doc­u­ment.ad­de­ventlis­tener("dom­con­tentl

oaded", func­tion(){

var my­field = { la­bels: ["Jan­uary", "Fe­bru­ary", "March", "April", "May", "June", "July"],

datasets: [{ la­bel: "My First dataset", back­ground­color: 'rgb(255, 99, 132)', bor­der­color: 'rgb(255, 99, 132)', data: [0, 10, 5, 2, 20, 30, 45], }] };

. . . ctx = doc­u­ment. getele­ment­byid('workarea4').get­con­text('2d'); chart = new Chart(ctx, { type: 'bar', op­tions: { }, data: my­field });

}); </script>

8. Pies cause trou­ble

In the­ory, a pie chart can be ren­dered along the same lines. Re­move the colour prop­er­ties to pre­vent uni­form ap­pear­ance, and set the type prop­erty to pie. Sadly, this does not quite work out – when done, the pie chart will fill the en­tire screen. This is caused by a spe­cial­ity of the pie ren­derer which uses the ‘larger’ of the two prop­er­ties to de­ter­mine pie ra­dius. var mypie = { la­bels: [“Jan­uary”,

“Fe­bru­ary”, “March”, “April”, “May”, “June”, “July”],

datasets: [{ la­bel: “My First dataset”,

data: [0, 10, 5, 2, 20, 30, 45], }]

}; ctx = doc­u­ment.getele­ment­byid(‘workarea2’). get­con­text(‘2d’); chart = new Chart(ctx, { type: ‘pie’, op­tions: { }, data: mypie });

9. Solve the prob­lem

Open the ‘in­dex.js’ file cre­ated in step 1. Be­gin by spec­i­fy­ing the graph type as line and adding the data to be vis­ually rep­re­sented as shown below.

<body> <div style="po­si­tion:ab­so­lute; top:0%;

left: 0%; width:49%; height:49%;"> <can­vas id="workarea" ></

can­vas></can­vas>

</div>

<div style="po­si­tion:ab­so­lute; top:0%;

left: 51%; width:29%; height:49%;">

<can­vas id="workarea2"></ can­vas></can­vas> </div>

10. the smart ap­proach…

An­other ap­proach to solve the prob­lem in­volves re-dis­abling the ‘main­tainaspec­tra­tio’ fea­ture. This way, the di­a­gram­ming en­gine is al­lowed to rescale the

di­a­gram as it sees fit, en­sur­ing that the en­tire cir­cle shows up on the screen. ctx = doc­u­ment.getele­ment­byid('workarea2'). get­con­text('2d'); chart = new Chart(ctx, { type: 'pie', op­tions: {main­tainaspec­tra­tio:false },

data: mypie });

11. im­prove pie colour­ing

Chart.js does not con­tain a ran­dom colour gen­er­a­tor – if you don’t pro­vide a colour ar­ray, colours won’t change. As de­sign­ing sys­tems based purely on colours is in­ef­fi­cient – many (of­ten high IQ and af­flu­ent) in­di­vid­u­als suf­fer from colour blind­ness. A nice way around the prob­lem is the ‘pat­ter­nomaly’ li­brary.

<script src="https://cdn.js­de­livr.net/npm/ pat­ter­[email protected]/dist/pat­ter­nomaly.js"></ script>

var mypie = { la­bels: ["Jan­uary", "Fe­bru­ary", "March", "April", "May", "June", "July"], datasets: [{ back­ground­color: [ pat­tern. draw('square', '#ff6384'),

pat­tern. draw('cir­cle', '#36a2eb'), pat­tern. draw('di­a­mond', '#cc65fe'),

pat­tern. draw('tri­an­gle', '#ffce56'),

pat­tern. draw('square', '#1f77b4'),

pat­tern. draw('cir­cle', '#ff7f0e'), pat­tern. draw('di­a­mond', '#2ca02c'), pat­tern. draw('zigzag-hor­i­zon­tal', '#17becf'), pat­tern. draw('tri­an­gle', '#7f7f7f') . . .

12. us­ing pat­terns

Ac­tu­ally ap­ply­ing the pat­tern is not dif­fi­cult. As shown above, sim­ply in­stan­ti­ate them us­ing the name from the fig­ure and a colour screen to be used as a back­ground. En­sure that the ar­ray con­tains enough el­e­ments to cover each mem­ber of the data field.

13. tooltip is­sues

Run­ning the pro­gram with en­abled de­vel­oper tools finds an in­ter­est­ing prob­lem. When pass­ing the mouse cursor over the chart el­e­ments, er­rors pop up. This is caused by the tooltip win­dow, which is not able to dis­cern colour in­for­ma­tion from pie el­e­ments loaded with a pat­tern.

14. over­write in­for­ma­tion

The prob­lem at hand can be reme­died by over­rid­ing parts of the tooltip’s el­e­ment. Chart.js lets you sub­mit event han­dlers that get called as a tooltip win­dow pops up – over­writ­ing ‘la­bel­color’ dis­ables the snoop­ing al­go­rithm re­spon­si­ble for the emis­sion of the warn­ing seen be­fore. chart = new Chart(ctx, { type: 'pie', op­tions: { main­tainaspec­tra­tio:false, tooltips: { call­backs: { la­bel­color: func­tion(tooltip­item, chart) { re­turn { bor­der­color: 'rgb(255, 0, 0)', back­ground­color: 'rgb(255, 0, 0)'

}

}, la­bel­text Color:func­tion(tooltip­item, chart){ re­turn '#543453'; }

} } }, data: mypie });

15. Add a ti­tle

Es­pe­cially when di­a­grams are in­tended for ex­port or sav­ing, adding a ti­tle im­proves the mean­ing­ful­ness of the in­for­ma­tion dis­played. The code shown next to this step takes care of the prob­lem ef­fec­tively – ad­di­tional cus­tomi­sa­tion, such as the choice of fonts, can be ac­com­plished with ad­di­tional pa­ram­e­ters. var chart = new Chart(ctx, { type: 'line', op­tions: {

ti­tle: { dis­play: true, text: 'Line Chart' } }, data: my­field

16. one more chart…

So far, our di­a­grams were lim­ited to one bit of in­for­ma­tion at a time. Adding a se­cond ‘level’ to a data field mo­ti­vates Chart.js to cre­ate a chart made up of more than one data set. The La­bels ar­ray is im­por­tant, as its omis­sion makes the pro­gram skip parts of the data.

var my­field2 = { la­bels: ["1", "2", "3", "4", "5", "6", "7"], datasets: [{ la­bel: "My First dataset", back­ground­color: 'rgb(255, 99, 132)', bor­der­color: 'rgb(255, 99, 132)', data: [0, 10, 5, 2, 20, 30, 45], }, { la­bel: "My se­cond dataset", fill­color: "rgba(151,187,205,0.2)", stroke­color: "rgba(151,187,205,1)", data: [28, 33, 40, 19, 12, 27, 9] }] };

17. Sci­en­tific chart­ing

Gen­er­at­ing the la­bel’s ar­ray can get te­dious. If your in­for­ma­tion is sourced from some­where where or­di­nal in­for­ma­tion is read­ily avail­able, the data ar­ray can also be pop­u­lated with an ar­ray of ‘Point[]’ fields. In this case, use the syn­tax shown below. data: [{ x: 10, y: 20 }, { x: 15, y: 10 }]

18. Ad­just place­ment of charts

The above-men­tioned spac­ing prob­lem makes po­si­tion­ing di­a­grams dif­fi­cult. Chart.js ad­dresses this prob­lem via the pad­ding at­tribute found in the op­tions field – it al­lows you to de­clare a keep-out zone on each of the four mar­gins of the con­tainer, thereby con­strain­ing ren­der­ing. var chart = new Chart(ctx, { type: ‘line’, op­tions: { lay­out: { pad­ding: { left: 30, right: 30, top: 30, bot­tom:30 } },

19. Set it glob­ally…

As­sign­ing lay­out set­tings to each di­a­gram is te­dious. A smarter ap­proach in­volves the ‘Chart.de­faults.global’ el­e­ment. It ex­poses the de­fault set­tings Chart.js will use for new di­a­grams, and can save a lot of code if mul­ti­ple di­a­grams are to be hosted next to one an­other. <script>

doc­u­ment.ad­de­ventlis­tener("dom­con­tentl

oaded", func­tion(){ Chart.de­faults.global.lay­out = {

pad­ding: { left: 30, right: 30, top: 30, bot­tom: 30

} };

20. Look at ex­am­ples

The Chart.js de­vel­op­ers pro­vide a set of ex­am­ples to show the frame­work in ac­tion. Sim­ply open http://www. chartjs.org/sam­ples/lat­est to take a look at the var­i­ous op­tions – the source code, usu­ally, is com­mented well.

21. Learn even more

Chart.js comes with ex­tremely de­tailed doc­u­men­ta­tion, which is hosted at https://www.chartjs.org/docs/lat­est. Sim­ply open it in a browser of choice, and nav­i­gate to the sec­tor which in­ter­ests you the most.

Newspapers in English

Newspapers from UK

© PressReader. All rights reserved.