Coder Social home page Coder Social logo

halfpastfouram / phpchartjs Goto Github PK

View Code? Open in Web Editor NEW
25.0 6.0 13.0 384 KB

A PHP library that makes it easy to generate data for ChartJS.

Home Page: https://halfpastfouram.github.io/phpchartjs/

License: GNU Affero General Public License v3.0

PHP 98.39% HTML 1.61%
chartjs composer php lock javascript

phpchartjs's Introduction

Stable

Latest Stable Version Total Downloads License composer.lock Build Status Code Climate Test Coverage Quality

Development

Latest Unstable Version Build Status

PHPChartJS

PHP OOP library for ChartJS

PHPChartJS acts as an interface between the ChartJS library and the server side code. Set up a chart in no time and have every aspect of the graph managable from your PHP code. This interface is set up to provide code completion in every scenario so you never have to guess or lookup what options are available for the chosen chart. The library is entirely object oriented.

This library is still in active development and aims to implement all options ChartJS has to offer. Check the Configuration milestone to view the progress of implementing all existing options.

Example use

<?php
use Halfpastfour\PHPChartJS\Chart\Bar;

$bar = new Bar();
$bar->setId("myBar");

// Set labels
$bar->labels()->exchangeArray(["M", "T", "W", "T", "F", "S", "S"]);

// Add apples
$apples = $bar->createDataSet();
$apples->setLabel("apples")
  ->setBackgroundColor("rgba( 0, 150, 0, .5 )")
  ->data()->exchangeArray([12, 19, 3, 17, 28, 24, 7]);
$bar->addDataSet($apples);

// Add oranges as well
$oranges = $bar->createDataSet();
$oranges->setLabel("oranges")
  ->setBackgroundColor("rgba( 255, 153, 0, .5 )")
  ->data()->exchangeArray([ 30, 29, 5, 5, 20, 3 ]);
  
// Add some extra data
$oranges->data()->append(10);

$bar->addDataSet($oranges);

// Render the chart
echo $bar->render();

The result generated by rendering the chart will look something like this:

<canvas id="myBar"></canvas>
<script>
window.onload=(function(oldLoad){return function(){
if( oldLoad ) oldLoad();
var ctx = document.getElementById( "myBar" ).getContext( "2d" );
var chart = new Chart( ctx, {"type":"bar","data":{"labels":["M","T","W","T","F","S","S"],"datasets":[{"data":[12,19,3,17,28,24,7],"label":"apples","backgroundColor":"rgba( 0, 150, 0, .5 )"},{"data":[30,29,5,5,20,3,10],"label":"oranges","backgroundColor":"rgba( 255, 153, 0, .5 )"}]}} );
}})(window.onload);
</script>

Callbacks

You can provide javascript callbacks with ease:

$myCallback = "function(item){ console.log(item); }";
$bar->options()->getTooltips()->callbacks()->setAfterBody($myCallback);

Rendering

Rendering the chart creates some HTML and some JavaScript. The JavaScript contains a JSON object providing the necessary configuration for ChartJS. Every part of the configuration can be cast to an array or a JSON object.

Render isolated part of the configuration:

$json = $myChart->options()->getScales()->jsonSerialize();

Or return an array containing the set configuration:

$options = $myChart->options()->getScales()->getArrayCopy();

Pretty mode

If you're not a fan of the long lines of code that are being generated you can force the rendering to be done in pretty mode, see the following example.

// Render in pretty mode
$bar->render(true);

Want to see more? Fork this project and take a look at the examples in the test folder to explore the different options.

Configuration options

Every option that is supported by ChartJS will be made available in this library.

Layers

ChartJS requires you to build a JSON object containing the configuration options you want to set for the current chart. These options are spread over multiple layers inside the configuration object. Accessing these layers with PHPChartJS is super easy.

Let's say we wanted to access the chart's getAnimation subtree within the options subtree:

$getAnimation = $myChart->options()->getAnimation();

You can now adjust any of ChartJS's getAnimation settings by using the getters and setters provided in that particular class.

Collections

If ChartJS requires an array with certain items as subsets in a configuration option that array will be represented by a collection in PHPChartJS. The collection can always by accessed directly to add, remove and replace values.

In some cases a specific object with a predetermined list of options is required in a collection. In these cases methods will be provided to create a new instance of said object and adding it to the collection.

Datasets are stored in a collection:

// Create new dataset
$dataset = $myChart->createDataSet();
... (add data to the dataset)
$myChart->addDataSet($dataset);

But the actual data in a dataset is also stored inside a collection:

// Create new dataset
$dataset = $myChart->createDataSet();

// Add some data 
$dataset->data()->append(1)->append(2);

// Prepend some data
$dataset->data()->prepend(0);

// Replace data at certain position
$dataset->data()->offsetSet(1, 3);

// Retrieve data from certain position
$value = $dataset->data()->offsetGet(1); // 3

// Add a lot of data at once whilst returning the old values
$oldData = $dataset->data()->exchangeArray([1, 2, 3]); // array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

$myChart->addDataSet($dataset);

For more information about the collections visit the halfpastfouram/collection project.

Installation

Using composer

$ composer require halfpastfouram/phpchartjs

Development

This project uses composer, which should be installed on your system. Most Linux systems have composer available in their PHP packages. Alternatively you can download composer from getcomposer.org.

If you use the PhpStorm IDE then you can simply init composer through the IDE. However, full use requires the commandline. See PhpStorm help, search for composer.

To start development, do composer install from the project directory.

Remark Do not use composer update unless you changed the dependency requirements in composer.json. The difference is that composer install will use composer.lock read-only, while composer update will update your composer.lock file regardless of any change. As the composer.lock file is committed to the repo, other developers might conclude dependencies have changed, while they have not.

phpchartjs's People

Contributors

artggd avatar gbonnema avatar halfpastfouram avatar joerg-rauscher avatar sandermuller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

phpchartjs's Issues

Option/Scale adapted for serialization

Option/Scale had 3 methods for gridLines(), scaleLabels() and ticks() to return the objects and create if necessary. For serialization a getter starting with "get" or "is" is necessary. This getter should be added for all 3 methods. It should return the field without any transformations or checks.

Refactor chart types to reduce code smell.

In almost every chart type there are two methods present that are almost identical to those in each other chart type.

The methods options and createDataSet should be moved to the abstract Chart class whilst preserving code completion.

Test Factory

Write unit tests for:

  • - /Halfpastfouram/PHPChartJS/Factory

Committing composer.lock

See the discussion on https://stackoverflow.com/questions/12896780/should-composer-lock-be-committed-to-version-control#12896850

Main answer is "Yes, commit composer.lock". In the same discussion Josh Johnson presents arguments against committing composer.lock. In summary he claims:

  1. composer.json should lock version (in stead of requiring >= 1.0 it should be 1.0)
  2. composer.lock is a derived dependency file that does not explicitly state the required version, causing each "composer update" to potentially change the dependencies.

Needs discussion.

Test GlobalConfig

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\ConfigDefaults\GlobalConfig.php

Test Animation

Write a unit test for

  • - Halfpastfour\PHPChartJS\Options\Animation

Test XAxisCollection

Write unit tests for

  • - \Halfpastfouram\PHPChartJS\Options\Scales\XAxisCollection

Add dataset to a chart changes the owner

When a user currently adds a dataset to a chart, the user cannot use the same dataset for a different chart. The reason is that when adding a dataset to a chart, the chart changes the owner in the dataset to itself. If the user would share the dataset between charts, then the last chart that has the dataset added becomes the owner of the dataset. The result is undefined.

$dataSet = new DataSet; /* Then add some data to dataset */
$chart1->addDataSet($dataSet);
$chart2->addDataSet($dataSet);

This code will lead to $dataSet being owned by $chart2. The results for $chart1 are undefined.

The questions are:

  1. Documentation necessary?
  2. Preventive action necessary? F.i. preventing the add if the dataset already has an owner
  3. Making the add independent of the object. F.i. add by value using a clone of the object.

Test ChartOwned

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\ChartOwned
  • - \Halfpastfouram\PHPChartJS\ChartOwnedInterface

Test ScaleLabel

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\Options\Scales\ScaleLabel

Test Renderer

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\Renderer

Unittest Chart

Write a unit test for

  • namespace Halfpastfour\PHPChartJS\Chart

Remark. The javascript part of Chart->Render we will not test for now (and maybe never).

Test Collection

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\Collection
  • - \Halfpastfouram\PHPChartJS\CollectionInterface

Test Gridlines

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\Options\Scales\GridLines.php

Test Ticks

Write unit tests for

  • - \Halfpastfouram\PHPChartJS\Options\Scales\Ticks

Test DataSet

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\DataSet

Test Labels

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\Options\Legends\Labels

Unittest Hover

Write a unittest for

  • Halfpastfour\PHPChartJS\Options\Hover

Test XAxis

Write a unit test for

  • - Halfpastfour\PHPChartJS\Options\Scales\XAxis

Unittest Title

Write a unittest for

  • Halfpastfour\PHPChartJS\Options\Title

Delegate ArraySerializable cannot access subclass properties

The access modifiers for properties in subclasses extending a superclass that has the ArraySerializable trait prevent the getArrayCopy method from collecting necessary data.

The class RadarDataSet and LineDataSet both have a number of properties listed as private. Those are inaccessible for the method in the trait until the access modifier is set to protected instead of private.

ArraySerializable should only retrieve through specific getters

The trait ArraySerializable implements getArrayCopy in a way that only retrieves through getters that start with the string "get" or the string "is" (for boolean). It does not retrieve getters with other prefixes, like the getter layout in Options().

The initial consideration was to changet getArrayCopy to include getters that have identical names to the instance fields. Some of these fields are actually objects on which ArraySerializable does a getArrayCopy. The problem is that not all objects have getArrayCopy. For instance the owner should never be serialized through getArrayCopy.

We agreed to limit ArraySerializable to retrieve only fields that have "get" or "is" as a prefix to the fieldsname (with first character capitalized). We will have to alter some of the getters to include "get" or "is" in order for them to be serialized properly.

Test Options

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\Options

Unittest Scales

Write a unittest for

  • Halfpastfour\PHPChartJS\Options\Scales

Unittest Layout

Write a unittest for

  • Halfpastfour\PHPChartJS\Options\Layout

Some getters miss "get"

Adapt TestUtils::getAttributes to getters like data() the do not have "is" or "get" in front of them. Make sure to only execute getter if method is correc.t.

Test ArraySerializable

Write unit tests for:

  • - \Halfpastfouram\PHPChartJS\Delegate\ArraySerializable
  • - \Halfpastfouram\PHPChartJS\ArraySerializableInterface

Trait ArraySerializable calls getArrayCopy on external objects

Classes that contain expressions use the Zend\Json\Expr object to store the expression (and using jsonSerialize to create a javascript expression). However, Zend\Json\Expr does not contain any getArrayCopy while ArraySerializable attempts to call it.

Solution is to use reflection the check the presence of getArrayCopy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.