Highcharts - parse json series - php

Im using this to draw column highcharts jsfiddle
i use this to gt JSON:
<?php
$query = mysql_query("SELECT
sales_raport_all.from_date,
sales_raport_all.to_date,
sales_raport_all.konto,
SUM(sales_raport_all.saldo_sprzedazy),
SUM(sales_raport_all.wartosc_kosztowa),
SUM(sales_raport_all.marza),
klienci_ax_all.sales_group,
klienci_ax_all.nazwa
FROM
sales_raport_all
INNER JOIN
klienci_ax_all
ON
sales_raport_all.konto=klienci_ax_all.konto_odbiorcy
WHERE
YEAR(from_date) = YEAR(CURDATE())
GROUP BY
sales_raport_all.from_date,
klienci_ax_all.sales_group
ORDER BY
sales_raport_all.from_date,
klienci_ax_all.sales_group");
$raw = array();
$dates = array();
while ($r = mysql_fetch_array($query)) {
$date = $r['from_date'];
if (!in_array($date, $dates)) $dates[] = $date;
$sales_group = $r['sales_group'];
$raw[$sales_group][$date] = intval($r['SUM(sales_raport_all.saldo_sprzedazy)']);
}
$data = array();
$data[0] = array('name' => "Date", 'data' => $dates);
foreach ($raw as $name => $d) {
$new_data = array('name' => $name, 'data' => array());
foreach ($dates as $date) {
$new_data['data'][] = isset($d[$date]) ? $d[$date] : 0;
}
$data[] = $new_data;
}
print json_encode($data);
in fiddle i use
chart3Options.series[0] = json[1];
...
is there a simple way to define all data in json? this data is variable and if i declare 11 variables and there will be only 7 then charts will not draw
JSON output for one date:
[{"name":"Date","data":["2014-01-01"]},{"name":"IN","data":[2580]},{"name":"KD","data":[5030]},{"name":"\u0141S","data":[12628]},{"name":"NN","data":[400]},{"name":"SG","data":[12979]},{"name":"TD","data":[15096]}]
// EDIT
i create new file:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Highcharts Example</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'column',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'test',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'test'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +': '+ this.y;
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: []
}
$.getJSON("test2.php", function(json) {
options.xAxis.categories = json[0]['category'];
options.series[0] = {};
options.series[0].name = json[0]['name'];
options.series[0].data = json[0]['data'];
chart = new Highcharts.Chart(options);
});
});
</script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</body>
</html>
and test2.php
<?php
$db_host = '******';
$db_user = '******';
$db_pass = '******';
$db_database = '******';
$link = mysql_connect($db_host,$db_user,$db_pass) or die('Nawiązanie połączenia z bazą danych nie było możliwe');
mysql_select_db($db_database,$link);
mysql_query("SET names UTF8");
$query = mysql_query("SELECT
sales_raport_all.from_date,
sales_raport_all.to_date,
sales_raport_all.konto,
SUM(sales_raport_all.saldo_sprzedazy),
SUM(sales_raport_all.wartosc_kosztowa),
SUM(sales_raport_all.marza),
klienci_ax_all.sales_group,
klienci_ax_all.nazwa
FROM
sales_raport_all
INNER JOIN
klienci_ax_all
ON
sales_raport_all.konto=klienci_ax_all.konto_odbiorcy
WHERE
YEAR(from_date) = YEAR(CURDATE())
GROUP BY
sales_raport_all.from_date,
klienci_ax_all.sales_group
ORDER BY
sales_raport_all.from_date,
klienci_ax_all.sales_group");
$result = array();
while($r = mysql_fetch_array($query)) {
$grupa = $r['sales_group'];
$datetime = $r['from_date'];
$result['name'][] = $datetime;
$result['category'][] = $grupa;
$result['data'][] = intval($r['SUM(sales_raport_all.saldo_sprzedazy)']);
}
$json = array();
array_push($json,$result);
print json_encode($json);
?>
JSON give me:
[{"name":["2014-01-01","2014-01-01","2014-01-01","2014-01-01","2014-01-01","2014-01-01"],"category":["IN","KD","\u0141S","NN","SG","TD"],"data":[2580,5030,12628,400,12979,15096]}]
Series looks greate but i dont know how to change category as in example http://jsfiddle.net/rubJS/

You can handle it in javascript. In other words, instead of defining variable for each <x,y> pair, return the data and let javascript construct the series.
For example, given your current output you can prepare X and Y values (in javascript) in separate arrays and write a function pushing these values into series. It can be done like this (using jQuery as an example):
function build_chart(x_values, y_values, options)
{
jQuery.each(x_values, function(item) {
options.xAxis.categories.push(x_values[item]);
});
var series = {
data: []
};
jQuery.each(y_values, function(item) {
series.data.push(parseInt(y_values[item]));
});
options.series.push(series);
chart = new Highcharts.Chart(options);
return chart;
}
Where variable options defines a chart template without series member (which is added by the above function)
EDIT
Following the edit in the question, here is the jsFiddle supporting it.
Note that the data in JSON is represented as array of arrays. First element in each array corresponds to the first category, second element in each array corresponds to the second category etc.

Apart from incorrect json format (which was mentioed) you need to push your dates as categorries in highcharts or use datetime type of axis, and then parse your date to timestamp.

Related

How can I count my table row and display to my highcharts

Can you guys help me with my problem?
My Highcharts graph working , But I don't have any idea to count my table cell in $as_name with month $created_date and display only gel data to my highcharts like categorie (month) and data to(as_name)count,
this is my database and my code,
Any help is well appreciated Thank you..
database
CREATE TABLE `tickets` (
`id` int(11) NOT NULL,
`as_name` varchar(50) NOT NULL,
`create_date` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|AS_name|creater_date|
---------------------
|gel |2020-12-21 |
|gel |2020-12-21 |
|jhon |2020-12-21 |
|gel |2020-12-21 |
|jhon |2020-12-21 |
---------------------
controller.
public function index()
{
$data['list'] = $this->data();
$this->load->view('dashboard');
}
public function data()
{
$data = $this->Dashboard_model->get_data();
$category = array();
$category['name'] = 'Month';
$series1 = array();
$series1['name'] = 'WordPress';
$series2 = array();
$series2['name'] = 'Code Igniter';
$series3 = array();
$series3['name'] = 'Highcharts';
foreach ($data as $row) {
$category['data'][] = $row->month;
$series1['data'][] = $row->wordpress;
$series2['data'][] = $row->codeigniter;
$series3['data'][] = $row->highchart;
}
$result = array();
array_push($result,$category);
array_push($result,$series1);
array_push($result,$series2);
array_push($result,$series3);
print json_encode($result, JSON_NUMERIC_CHECK);
}
model
public function get_data()
{
$this->db->select('month,wordpress,codeigniter,highchart');
$this->db->from('sample');
$query = $this->db->get();
return $query->result();
}
VIEW
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var options = {
colors: ['#058DC7', '#800080', '#F08080'],//line
chart: {
renderTo: 'model',
type: 'line',
marginRight: 130,
marginBottom: 100
},
title: {
text: 'Month',//title here
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'click'//side commment
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b>'+
this.x +': '+ this.y;
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 40,
borderWidth: 1
},
series: []
}
var url = <your web url> + "data1.json"; // assumes that your URL ends with a forward slash
$.getJSON("url", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
options.series[1] = json[2];
options.series[2] = json[3];
chart = new Highcharts.Chart(options);
});
});
</script>
<script type="text/javascript" src="http://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript" src="http://code.highcharts.com/modules/exporting.js"></script>
</head>
**body**
<div class="jumbotron" >
<div id="model" style="width: 600px; height: 400px; margin: 0 auto;" ></div>
</div>

Populate highcharts data using MySQL

I am new to web programming, I have personal project to track expenditure.
Straight to the point, I have database data contains this month and last month total expenditure. I am able to show it manually (by echo). But i can't pass the value to highcharts series. Due to many small separate data, i want to populate it manually using php/mysql rather than json.
Graph2.php
<?php
$mysql_hostname = "localhost";
$mysql_user = "root";
$mysql_password = "mypassword";
$mysql_database = "mytraining";
$bd = mysqli_connect($mysql_hostname, $mysql_user, $mysql_password, $mysql_database);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query2 = "select year(date) as y, month(date) as m, sum(amount) as p from expenditure_bak group by year(date), month(date) order by m ASC";
$sth = mysqli_query($bd, $query2);
$rows = array();
$rows['name'] = 'Revenue';
while($r = mysqli_fetch_array($sth)) {
$rows['data'][]= round($r['p'],2);
}
//echo join($rows['data'], ','); //able to display correct value 660.2,60
?>
PopupGraph.html
<?php
include('graph2.php');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Monthly Expenditure</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<style type="text/css">
${demo.css}
</style>
<script type="text/javascript">
$(function () {
$('#container').highcharts({
title: {
text: 'Monthly Expenditure'
},
xAxis: {
categories: ['Jun', 'Jul']
},
yAxis: [{
min: 0,
title: {
text: ''
}
}, {
min: 0,
opposite: false, //optional, you can have it on the same side.
title: {
text: 'Average'
}
}
],
labels: {
items: [{
html: 'Monthly Expenditure',
style: {
left: '50px',
top: '18px',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'black'
}
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y
/*+ '<br/>' + 'Total: ' + this.point.stackTotal*/;
}
},
series: [{
type: 'spline',
name: 'Average',
yAxis: 1, //to make y axis
//data: [660.2,60], //able to show correct graph with static input
data: [<?php echo join($rows[data], ',') ?>],
marker: {
lineWidth: 2,
lineColor: Highcharts.getOptions().colors[3],
fillColor: 'white'
}
}]
});
});
</script>
</head>
<body>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
</html>
So, what is the correct code to be put inside data: [] in the highcharts series.
Output should be like JSFiddle but using dynamic data from database obviously.
Finally, I want to display something like
Expenditure Tracking
You will likely need to encode your data. I recommend that you take a look at the answer from here Pass a PHP array to a JavaScript function. Based on this, you should be able to do something like this:
JSON.parse(<?php echo json_encode(join($rows[data], ',')) ?>);
then you should be able to get the result that you want. You might not need the JSON.parse.

Highcharts multiple series json from php

Hi guys i need help with Highcharts library, i have this array coming from php,
[{"name":"25% en cambio de aceite 76 lubricants","data":[["2015-09-07",1],["2015-09-23",2],["2015-09-24",3],["2015-09-30",3]]},{"name":"10% Descuento en filtro de aceite","data":[["2015-09-07",1],["2015-09-23",2],["2015-09-24",3],["2015-09-30",3],["2015-10-03",3],["2015-10-05",1],["2015-10-09",1],["2015-10-10",1]]}]
I need to show this as line chart dynamically, but have been unable to do it, i believe the error comes from the quotes in dates, needs to be in format [Date.UTC(2015, 2, 6), 3]
This is my php function that returns the json data
public function actionTransactionsRedeemed() {
// Transacciones Totales redimidas por merchant
$sql = "SELECT DISTINCT `transaction`.idPromotion, promotion.`name` FROM `transaction` INNER JOIN promotion ON `transaction`.idPromotion = promotion.idPromotion WHERE `transaction`.idMerchant = 2 AND `transaction`.idPromotion IS NOT NULL";
$idPromotion = Yii::app()->db->createCommand($sql)->queryAll();
$idPromotions = array();
$tempArray = array();
$result = array();
$i = 1;
$rs = array();
foreach($idPromotion as $i){
//process each item here
$id = $i["idPromotion"];
$tempArray['name'] = $i["name"];
$sql = "SELECT count(*) AS count, DATE(`transaction`.date) AS `date` FROM `transaction` WHERE `transaction`.idMerchant = 2 AND `transaction`.idPromotion = $id GROUP BY DATE(`transaction`.date)";
$transactionsRedeemed = Yii::app()->db->createCommand($sql)->queryAll();
foreach($transactionsRedeemed as $item2){
$rs[0] = $item2['date'];
$rs[1] = $item2['count'];
$tempArray['data'][] = $rs;
$rs = array();
}
$i++;
array_push($result, $tempArray);
}
//$result = json_encode($result, JSON_NUMERIC_CHECK);
//echo json_decode($result);
print json_encode($result, JSON_NUMERIC_CHECK);
}
And this is the Jquery that builds the chart
$(document).ready(function() {
var options = {
chart: {
type: 'spline',
renderTo: 'chart-merchant-day',
defaultSeriesType: 'spline',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Total de promociones redimidas',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: { // don't display the dummy year
month: '%e. %b',
year: '%b'
},
labels: {
align: 'center',
x: -3,
y: 20,
formatter: function() {
return Highcharts.dateFormat('%l%p', this.value);
}
}
},
yAxis: {
title: {
text: 'Transacciones'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return Highcharts.dateFormat('%l%p', this.x-(24000*3600)) +'-'+ Highcharts.dateFormat('%l%p', this.x) +': <b>'+ this.y + '</b>';
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'Count'
}],
credits: false
}
// Load data asynchronously using jQuery. On success, add the data
// to the options and initiate the chart.
jQuery.get('?r=/transactions/transactionsRedeemed', null, function(tsv) {
var lines = [];
traffic = [];
var data = $.parseJSON(tsv);
var x = 0;
//console.log(tsv);
$.each(data, function(i, item) {
//alert(item);
//console.log(item);
$.each(item, function(y, item2) {
if(y == "data"){
//console.log(item2);
try {
tsv = item2;
// split the data return into lines and parse them
tsv = tsv.split(/\n/g);
jQuery.each(tsv, function(i, line) {
line = line.split(/\t/);
options.series[x].data.push([Date.parse(line[0]),line[1]]);
/*date = Date.parse(line[0] +' UTC');
traffic.push([
date,
parseInt(line[1].replace(',', ''), 10)
]);*/
});
} catch (e) { }
options.series[x].data = traffic;
} else if(y == "name"){
options.series[x].name = item2;
}
});
x++;
});
chart = new Highcharts.Chart(options);
//console.log(tsv.replace(/\"/g, ""));
//tsv = tsv.replace(/\"/g, "");
});
});
Any help will be greatly appreciated, im so exhausted at this point.
The function is actually simpler,
jQuery.get('?r=/transactions/transactionsRedeemed', null, function(tsv) {
var data = $.parseJSON(tsv);
$.each(data, function (i, item) {
options.series.push({
name: item['name'],
data: []
});
$.each(item['data'], function (j, dataitem) {
var dataitemvalue = null;
try {
dataitemvalue = [Date.parse(dataitem[0]), dataitem[1]];
} catch (e) {}
options.series[i].data.push(dataitemvalue);
});
});
chart = new Highcharts.Chart(options);
});
JSFiddle demo

Highcharts Display values from sql via json

Hello I try to use Highcharts with data's from an sql Database by using json.
There are all doing but I can't see any values
I get the Data's with this script:
<?php
header('content-type: text/html; charset=utf-8');
include("db.inc.php");
$con = mysql_connect(DB_SERVER, DB_USER, DB_PASSWOR
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db(DB_NAME, $con);
$sth0 = mysql_query("SELECT `DATETIME` FROM `dg_wall24` WHERE DATETIME >
NOW()INTERVAL 1 HOUR");
$rows0 = array();
$rows0['name'] = 'DATETIME';
while($r0 = mysql_fetch_array($sth0)) {
$rows0['data'][] = $r0['DATETIME'];
}
$sth1 = mysql_query("SELECT `dg_t01` FROM `dg_wall24` WHERE DATETIME >
NOW()INTERVAL 1 HOUR");
$rows1 = array();
$rows1['name'] = 'dg_t01';
while($r1 = mysql_fetch_array($sth1)) {
$rows1['data'][] = $r1['dg_t01'];
}
$sth2 = mysql_query("SELECT `dg_h01` FROM `dg_wall24` WHERE DATETIME >
NOW() INTERVAL 1 HOUR");
$rows2 = array();
$rows2['name'] = 'dg_h01';
while($r2 = mysql_fetch_array($sth2)) {
$rows2['data'][] = $r2['dg_h01'];
}
$result = array();
array_push($result,$rows0);
array_push($result,$rows1);
array_push($result,$rows2);
print json_encode($result);
mysql_close($con);
?>
The Result:
[{"name":"DATETIME","data":["2013-04-27 08:17:52","2013-04-27 08:22:52","2013-04-27 08:27:53","2013-04-27 08:32:54","2013-04-27 08:37:55","2013-04-27 08:42:55","2013-04-27 08:47:56","2013-04-27 08:52:57","2013-04-27 08:57:58","2013-04-27 09:02:58","2013-04-27 09:07:59","2013-04-27 09:13:00"]},{"name":"dg_t01","data":["22.40","22.40","22.40","22.40","22.30","22.30","22.40","22.40","22.40","22.40","22.40","22.40"]},{"name":"dg_h01","data":["40.20","40.40","40.50","40.80","40.70","40.70","40.80","40.90","41.00","41.00","40.90","40.70"]}]
In the Highchart I can See the timeline on the x Axis and the name of the values but no line and no values.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Highcharts Example</title>
<script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 40
},
title: {
text: 'Dachgeschoss',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
//categories: []
},
yAxis: {
title: {
text: 'Temperatur & Luftfeuchtigkeit'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +': '+ this.y;
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: []
}
$.getJSON("data2.php", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
options.series[1] = json[2];
chart = new Highcharts.Chart(options);
});
});
</script>
</head>
<body>
<script src="js/highcharts.js"></script>
<script src="js/modules/exporting.js"></script>
<script type="text/javascript" src="js/themes/gray.js"></script>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</body>
</html>
It is possible that I have an problem with the Dataformat (float, int...) or with the Point in the values?
Many thanks for the help
The problem is indeed that your JSON object contains String values instead of Float values for your data:
{ ... "data":["40.20","40.40","40.50", ... ]}
I don't know what the field type in your database is, and I'm no PHP coder, but you could try setting the JSON_NUMERIC_CHECK option on json_encode.
If that doesn't work for you, you could also convert the Strings using parseFloat in Javascript:
for (var i = 0, num; num = json[1].data[i]; i++)
{
json[1].data[i] = parseFloat(num);
}
See my example on Fiddle.

Highchart LineChart MySQL data

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script src='http://code.highcharts.com/highcharts.js' type='text/javascript'> </script>
<script src='http://code.highcharts.com/modules/exporting.js' type='text/javascript'> </script>
</head>
<body>
<?php
$con = mysql_connect('localhost', 'root', '123456') or die('Error connecting to server');
mysql_select_db("aplikace", $con);
$SQL1 = "SELECT * FROM data";
$result1 = mysql_query($SQL1);
$data1 = array();
while ($row = mysql_fetch_array($result1)) {
$data1[] = $row['cas'];
}
$result2 = mysql_query($SQL1);
$data2 = array();
while ($row = mysql_fetch_array($result2)) {
$data2[] = hexdec($row['pars_data']);
}
?>
<script type="text/javascript">
$(document).ready(function() {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line'
},
title: {
text: 'Comming Data'
},
xAxis: {
categories: ['<?php echo join($data1, "','") ?>'],
},
yAxis: {
min:0,
},
legend: {
layout: 'vertical',
backgroundColor: '#FFFFFF',
align: 'left',
verticalAlign: 'top',
x: 50,
y: 35,
floating: true,
shadow: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [ {
name: 'Data',
data: ['<?php echo join($data2, "','") ?>'],
// pointStart: 0
//pointInterval
},
]
});
});
</script>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
Hi guys, I dont kwno where I have a mistake, could you help me please? On X-axis should be the datetime from column CAS-> it works but it doesnt display column PARS_DATA. Thanks for your help, thanks.
MySQL TABLE screen:
Chart which I see:
You should convert your date time field to unix timestamp for process on it.
so strtotime function is good idea.
In your code, follow this :
$result=mysql_query($sql)or die(mysql_error());
if(mysql_num_rows($result)>0){
while($row=mysql_fetch_array($result))
{
$uts=strtotime($row['time']); //convert to Unix Timestamp
$date=date("l, F j, Y H:i:s",$uts); //standard template for draw chart
echo $date . "\t" . $row['new_cost']. "\n"; //only this template work
}
$sql: your sql query text.
$result: feedback.
$row['new_cost']: my field for cost.
for more details, follow this link
good luck

Categories