mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
Charts: Add chart_event option, provide other data formats & add demo
This commit is contained in:
parent
1af1de85e1
commit
48d6ba5007
693
docs/example-widget-chart.html
Normal file
693
docs/example-widget-chart.html
Normal file
@ -0,0 +1,693 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery plugin: Tablesorter 2.0 - Chart Widget</title>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="js/jquery-latest.min.js"></script>
|
||||
<script src="js/jquery-ui-latest.min.js"></script>
|
||||
|
||||
<!-- Demo stuff -->
|
||||
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css">
|
||||
<link class="ui-theme" rel="stylesheet" href="css/jquery-ui.min.css">
|
||||
<link rel="stylesheet" href="css/jq.css">
|
||||
<link rel="stylesheet" href="css/prettify.css">
|
||||
<script src="js/prettify.js"></script>
|
||||
<script src="js/docs.js"></script>
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
|
||||
<!-- Google charts -->
|
||||
<script src="http://www.google.com/jsapi"></script>
|
||||
|
||||
<!-- Tablesorter: required -->
|
||||
<link rel="stylesheet" href="../css/theme.blue.css">
|
||||
<script src="../js/jquery.tablesorter.js"></script>
|
||||
<script src="../js/jquery.tablesorter.widgets.js"></script>
|
||||
|
||||
<script src="../js/widgets/widget-cssStickyHeaders.js"></script>
|
||||
<script src="../js/widgets/widget-columnSelector.js"></script>
|
||||
<script src="../js/widgets/widget-pager.js"></script>
|
||||
<script src="../js/widgets/widget-chart.js"></script>
|
||||
|
||||
<style>
|
||||
h1 { font-size: 28px; }
|
||||
/* override jQuery UI overriding Bootstrap */
|
||||
.accordion .ui-widget-content a {
|
||||
color: #337ab7;
|
||||
}
|
||||
/* .spacer in docs css is set to height:800px for stickyHeader demo */
|
||||
#pager .spacer { height: auto; }
|
||||
.wrapper { padding: 5px; }
|
||||
</style>
|
||||
|
||||
<style id="css">#pager div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#pager-container .spacer {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
#pager-container,
|
||||
#chart-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#chart-container > div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#chartbar {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#chartbar i.clickable {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
i.clickable {
|
||||
cursor: pointer;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
i.clickable.disabled,
|
||||
i.clickable.disabled:hover {
|
||||
cursor: not-allowed;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
i.active.clickable,
|
||||
i.clickable:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/*** custom css only popup ***/
|
||||
.columnSelector, .hidden, #chart-container {
|
||||
display: none;
|
||||
}
|
||||
#colSelect:checked + label {
|
||||
background: #5797d7;
|
||||
border-color: #555;
|
||||
}
|
||||
#colSelect:checked ~ #columnSelector {
|
||||
display: block;
|
||||
}
|
||||
#chartSelect:checked + label {
|
||||
background: #5797d7;
|
||||
border-color: #555;
|
||||
}
|
||||
.columnSelector {
|
||||
width: 120px;
|
||||
position: absolute;
|
||||
margin-top: 5px;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
border: #ccc 1px solid;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.columnSelector label {
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
.columnSelector label:nth-child(1) {
|
||||
border-bottom: #99bfe6 solid 1px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.columnSelector input {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.columnSelector .disabled {
|
||||
color: #ddd;
|
||||
}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="banner">
|
||||
<h1>table<em>sorter</em></h1>
|
||||
<h2>Chart Widget (beta)</h2>
|
||||
<h3>Flexible client-side table sorting</h3>
|
||||
<a href="index.html">Back to documentation</a>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p></p>
|
||||
<br>
|
||||
<div id="root" class="accordion">
|
||||
|
||||
<h3 id="notes"><a href="#">Notes</a></h3>
|
||||
<div>
|
||||
<ul>
|
||||
<li>This widget will <strong>only work</strong> in tablesorter version 2.16+ and jQuery version 1.7+.</li>
|
||||
<li>It only provides data for charts.</li>
|
||||
<li>Currently it provides data for the following chart libraries:
|
||||
<ul>
|
||||
<li><a href="https://developers.google.com/chart/">Google charts</a></li>
|
||||
<li><a href="http://www.highcharts.com/">Highcharts</a></li>
|
||||
<li><a href="http://www.fusioncharts.com/">FusionCharts</a></li>
|
||||
</ul>
|
||||
More details are available within the named "Setup" sections below.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h3 id="options"><a href="#">Options</a></h3>
|
||||
<div>
|
||||
<div>
|
||||
<span class="label label-info">TIP!</span> Click on the link in the function column to reveal full details (or <a href="#" class="toggleAll">toggle</a>|<a href="#" class="showAll">show</a>|<a href="#" class="hideAll">hide</a> all) or double click to update the browser location.
|
||||
</div>
|
||||
|
||||
<table class="options tablesorter-blue">
|
||||
<thead>
|
||||
<tr><th class="option">Option</th><th class="defaults">Default</th><th class="sorter-false">Description</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr id="chart-inc-rows">
|
||||
<td><a href="#" class="permalink">chart_incRows</a></td>
|
||||
<td>'filtered' <span class="results">*</span></td>
|
||||
<td>Select which rows to include in the chart.
|
||||
<div class="collapsible">
|
||||
<p></p>
|
||||
This option allows you to select which rows to include in the chart data:
|
||||
<ul>
|
||||
<li><code>'a'</code> - Include <em>all</em> rows, even if the table has been filtered or partially hidden by the pager.</li>
|
||||
<li><code>'v'</code> - Include only <em>visible</em> rows, whether they are hidden by the pager or filter.</li>
|
||||
<li><code>'f'</code> - Include only <em>filtered</em> rows, even if the pager is only showing a select few rows.</li>
|
||||
</ul>
|
||||
<span class="results">*</span> Only the first letter is required, but the option will accept the full word (e.g. 'filtered' instead of 'f')
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="chart-use-selector">
|
||||
<td><a href="#" class="permalink">chart_useSelector</a></td>
|
||||
<td>false</td>
|
||||
<td>Use the columnSelector widget in place of the <code>chart_ignoreColumns</code> option.
|
||||
<div class="collapsible">
|
||||
<p></p>
|
||||
Set this option to <code>true</code> if using the columnSelector widget.
|
||||
<p></p>
|
||||
If using a custom column selector, then set this option to <code>false</code> and use the custom selector to update the <code>chart_ignoreColumns</code> option dynamically.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="chart-ignore-columns">
|
||||
<td><a href="#" class="permalink">chart_ignoreColumns</a></td>
|
||||
<td>[ ]</td>
|
||||
<td>Array of zero-based column indexes of columns to ignore.
|
||||
<div class="collapsible">
|
||||
<p></p>
|
||||
This option is used when the <code>chart_useSelector</code> option is <code>false</code> or if the columnSelector is set to "auto" mode.
|
||||
<p></p>
|
||||
Update this option dynamically, if using a custom method to hide/indicate which columns are to be ignored when gathering data for the chart.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="chart-parsed">
|
||||
<td><a href="#" class="permalink">chart_parsed</a></td>
|
||||
<td>[ ]</td>
|
||||
<td>Array of zero-based column indexes of columns that must used parsed data for charting.
|
||||
<div class="collapsible">
|
||||
<p></p>
|
||||
Parsed data is gathered from the table cache, which is parsed the designated parser for that column.
|
||||
<p></p>
|
||||
This option can be updated dynamically.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="chart-layout">
|
||||
<td><a href="#" class="permalink">chart_layout</a></td>
|
||||
<td>{ 0: 'string' }</td>
|
||||
<td>Object containing the format needed by the chart for each column.
|
||||
<div class="collapsible">
|
||||
<p></p>
|
||||
By default, all columns will have their values converted to numbers. Prior to sending the value to tablesorter's <a href="index.html#function-formatfloat"><code>formatFloat</code></a> function, the value will have all non-digit characters stripped out.
|
||||
<p></p>
|
||||
Set the zero-based column index of the desired column to <code>'s'</code> (only the first letter is needed) to pass the cell value to the chart as a string.
|
||||
<p></p>
|
||||
This option can be updated dynamically.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="chart-label-col">
|
||||
<td><a href="#" class="permalink">chart_labelCol</a></td>
|
||||
<td>0</td>
|
||||
<td>Set a zero-based column index for the column to be used as a chart label.
|
||||
<div class="collapsible">
|
||||
<p></p>
|
||||
The chart label (independent variable) is usually the first array value in each nested array (at least for Google charts). In this demo, it is the Year.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="chart-sort">
|
||||
<td><a href="#" class="permalink">chart_sort</a></td>
|
||||
<td>[ [ 0,0 ] ]</td>
|
||||
<td>Sort a specific column of data using the same format as tablesorter's <code>sortList</code> option; but for a single column.
|
||||
<div class="collapsible">
|
||||
<p></p>
|
||||
Set this value to be an array contained within an array using the following format: <code>[[ column, direction ]]</code>
|
||||
<p></p>
|
||||
<span class="label label-info">* Note *</span> It would be best to sort the same column as the <code>chart_labelCol</code> to keep the axis ordered properly; but that is up to you ;)
|
||||
<p></p>
|
||||
<ul>
|
||||
<li><code>column</code> - zero-based index of the column to sort.</li>
|
||||
<li><code>direction</code> - sort direction; <code>0</code> indicates an ascending sort, and <code>1</code> indicates a descending sort is to be used.</li>
|
||||
</ul>
|
||||
<span class="label warning">* Note *</span> Anything other than <code>1</code> as the sort direction will set an ascending sort.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="chart-event">
|
||||
<td><a href="#" class="permalink">chart_event</a></td>
|
||||
<td>'chartData'</td>
|
||||
<td>The chart data will be updated when this event is triggered on the table.
|
||||
<div class="collapsible">
|
||||
<p></p>
|
||||
Trigger a chart data update, then get the data as follows:
|
||||
<pre class="prettyprint lang-js">var $table = $('table').trigger('chartData'),
|
||||
data = $table[0].config.chart.data;
|
||||
chartData( data ); // custom function to chart the data</pre>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3 id="google"><a href="#">Setup - Google Charts</a></h3>
|
||||
<div>
|
||||
The data used by Google charts is an array of arrays in this format:
|
||||
<pre class="prettyprint lang-js">[
|
||||
[ "Year", "Sales", "Expenses" ],
|
||||
[ "2004", 1000, 400 ],
|
||||
[ "2005", 1170, 460 ],
|
||||
[ "2006", 660, 1120 ],
|
||||
[ "2007", 1030, 540 ]
|
||||
]</pre>
|
||||
Access the data as follows:
|
||||
<pre class="prettyprint lang-js">var $table = $('table').trigger('chartData'),
|
||||
options = { /* set up options here */ },
|
||||
rawdata = $table[0].config.chart.data,
|
||||
data = google.visualization.arrayToDataTable( rawdata ),
|
||||
// bar chart example
|
||||
chart = new google.visualization.BarChart( $('#chart')[0] );
|
||||
chart.draw(data, options);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<h3 id="highcharts"><a href="#">Setup - Highcharts</a></h3>
|
||||
<div>
|
||||
The data used by Highcharts is an array of objects in this format:
|
||||
<pre class="prettyprint lang-js">// categories
|
||||
[ '2004', '2005', '2006', '2007' ]
|
||||
|
||||
// series
|
||||
[{
|
||||
name: 'Sales',
|
||||
data: [ 1000, 1170, 660, 1030 ]
|
||||
}, {
|
||||
name: 'Expenses',
|
||||
data: [ 400, 460, 1120, 540 ]
|
||||
}]</pre>
|
||||
Access the data as follows:
|
||||
<pre class="prettyprint lang-js">var $table = $('table').trigger('chartData');
|
||||
|
||||
$('#chart').highcharts({
|
||||
chart: { type: 'column' },
|
||||
xAxis: { categories: $table[0].config.chart.categories },
|
||||
series: $table[0].config.chart.series
|
||||
});
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<h3 id="fusioncharts"><a href="#">Setup - FusionCharts</a></h3>
|
||||
<div>
|
||||
The data used by FusionCharts is an array of objects in this format:
|
||||
<pre class="prettyprint lang-js">// category
|
||||
[
|
||||
{"label": "2004"},
|
||||
{"label": "2005"},
|
||||
{"label": "2006"},
|
||||
{"label": "2007"}
|
||||
]
|
||||
// dataset
|
||||
[{
|
||||
"seriesname": "Sales",
|
||||
"data": [
|
||||
{"value": "1000"},
|
||||
{"value": "1170"},
|
||||
{"value": "660"},
|
||||
{"value": "1030"}
|
||||
]
|
||||
},{
|
||||
"seriesname": "Expenses",
|
||||
"data": [
|
||||
{"value": "400"},
|
||||
{"value": "600"},
|
||||
{"value": "1120"},
|
||||
{"value": "540"}
|
||||
]
|
||||
}]</pre>
|
||||
Access the data as follows:
|
||||
<pre class="prettyprint lang-js">var $table = $('table');
|
||||
$table.trigger('chartData');
|
||||
|
||||
FusionCharts.ready(function () {
|
||||
var analysisChart = new FusionCharts({
|
||||
dataFormat: 'json',
|
||||
dataSource: {
|
||||
"chart": {
|
||||
// ...
|
||||
},
|
||||
"categories": [{
|
||||
"category": $table[0].config.chart.category
|
||||
}],
|
||||
"dataset": $table[0].config.chart.dataset,
|
||||
},
|
||||
// other options
|
||||
}).render();
|
||||
});</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<p></p>
|
||||
|
||||
<h1>Google Charts Demo</h1>
|
||||
<div id="demo"><div id="chart-container">
|
||||
<div id="chart"></div>
|
||||
<p></p>
|
||||
<div id="chartbar">
|
||||
<i class="fa fa-cube active clickable toolti" title="3D Pie Chart" data-toggle="tooltip" data-placement="top"></i>
|
||||
<i class="fa fa-pie-chart clickable" title="Pie Chart" data-toggle="tooltip" data-placement="top"></i>
|
||||
<i class="fa fa-line-chart clickable" title="Line Graph" data-toggle="tooltip" data-placement="top"></i>
|
||||
<i class="fa fa-area-chart clickable" title="Area Graph" data-toggle="tooltip" data-placement="top"></i>
|
||||
<i class="fa fa-bar-chart clickable" title="Vertical Bar Chart" data-toggle="tooltip" data-placement="top"></i>
|
||||
<i class="fa fa-tasks fa-rotate-90 clickable" title="Stacking Vertical Bar Chart" data-toggle="tooltip" data-placement="top"></i>
|
||||
<i class="fa fa-align-left clickable" title="Horizontal Bar Chart" data-toggle="tooltip" data-placement="top"></i>
|
||||
<i class="fa fa-tasks fa-rotate-180 clickable" title="Stacking Horizontal Bar Chart" data-toggle="tooltip" data-placement="top"></i>
|
||||
</div>
|
||||
<p></p>
|
||||
</div>
|
||||
|
||||
<!-- ColumnSelector -->
|
||||
<label for="colSelect" class="btn btn-default btn-sm" data-toggle="tooltip" data-placement="top" title="Toggle visible columns">
|
||||
<input id="colSelect" type="checkbox" class="hidden">
|
||||
<i class="fa fa-table"></i> Column
|
||||
<div id="columnSelector" class="columnSelector"></div>
|
||||
</label>
|
||||
<!-- Chart -->
|
||||
<label for="chartSelect" class="btn btn-default btn-sm" data-toggle="tooltip" data-placement="top" title="Toggle chart visibility">
|
||||
<input id="chartSelect" type="checkbox" class="hidden">
|
||||
<i class="fa fa-pie-chart"></i> Chart
|
||||
</label>
|
||||
<!-- row selector -->
|
||||
<span class="wrapper" data-toggle="tooltip" data-placement="top" title="Chart filtered, visible or all rows">
|
||||
<div class="btn-group chart-filter-all" data-toggle="buttons">
|
||||
<label class="btn btn-default btn-sm active">
|
||||
<input type="radio" name="getrows" data-type="filter" checked="checked"> Filtered
|
||||
</label>
|
||||
<label class="btn btn-default btn-sm">
|
||||
<input type="radio" name="getrows" data-type="visible"> Visible
|
||||
</label>
|
||||
<label class="btn btn-default btn-sm">
|
||||
<input type="radio" name="getrows" data-type="all"> All
|
||||
</label>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<table id="table" class="tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Year</th>
|
||||
<th>Sales</th>
|
||||
<th>Expenses</th>
|
||||
<th>Profit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>2004</td><td>$ 1,000</td><td>$ 400</td><td>$ 600</td></tr>
|
||||
<tr><td>2005</td><td>$ 1,170</td><td>$ 460</td><td>$ 710</td></tr>
|
||||
<tr><td>2006</td><td>$ 660</td><td>$ 1,120</td><td>($ 460)</td></tr>
|
||||
<tr><td>2007</td><td>$ 1,030</td><td>$ 540</td><td>$ 490</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- pager -->
|
||||
<div id="pager-container">
|
||||
<div id="pager">
|
||||
<form>
|
||||
<select class="pagesize" title="Select rows per page" data-toggle="tooltip" data-placement="left">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
<div class="spacer"><div class="separator"></div></div>
|
||||
<i class="fa fa-step-backward first clickable" title="First page"></i>
|
||||
<i class="fa fa-backward prev clickable" title="Previous page"></i>
|
||||
<div class="spacer"><div class="separator"></div></div>
|
||||
<span class="pagedisplay"></span>
|
||||
<div class="spacer"><div class="separator"></div></div>
|
||||
<i class="fa fa-forward next clickable" title="Next page"></i>
|
||||
<i class="fa fa-step-forward last clickable" title="Last page"></i>
|
||||
<div class="spacer"><div class="separator"></div></div>
|
||||
<select class="gotoPage" title="Select page" data-toggle="tooltip" data-placement="right"></select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Page Header</h1>
|
||||
<div>
|
||||
<pre class="prettyprint lang-html"><!-- Google charts -->
|
||||
<script src="//www.google.com/jsapi"></script>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="js/jquery-latest.min.js"></script>
|
||||
|
||||
<!-- Demo stuff -->
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css">
|
||||
<!-- buttons -->
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
|
||||
<!-- Tablesorter: required -->
|
||||
<link rel="stylesheet" href="../css/theme.blue.css">
|
||||
<script src="../js/jquery.tablesorter.js"></script>
|
||||
<script src="../js/widgets/widget-chart.js"></script>
|
||||
|
||||
<!-- Tablesorter: optional -->
|
||||
<script src="../js/jquery.tablesorter.widgets.js"></script>
|
||||
<script src="../js/widgets/widget-cssStickyHeaders.js"></script>
|
||||
<script src="../js/widgets/widget-columnSelector.js"></script>
|
||||
<script src="../js/widgets/widget-pager.js"></script></pre>
|
||||
</div>
|
||||
|
||||
<h1>Javascript</h1>
|
||||
<div id="javascript">
|
||||
<pre class="prettyprint lang-javascript"></pre>
|
||||
</div>
|
||||
|
||||
<h1>CSS</h1>
|
||||
<div id="css">
|
||||
<pre class="prettyprint lang-css"></pre>
|
||||
</div>
|
||||
|
||||
<h1>HTML</h1>
|
||||
<div id="html">
|
||||
<pre class="prettyprint lang-html"></pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script id="js">google.load("visualization", "1.1", {
|
||||
packages: ["bar", "corechart", "line"]
|
||||
});
|
||||
|
||||
$(function(){
|
||||
/* Initial settings */
|
||||
var $table = $('#table'),
|
||||
$chart = $('#chart'),
|
||||
$bar = $('#chartbar'),
|
||||
$rowType = $('[name=getrows]'),
|
||||
$icons = $('#chart-container i'),
|
||||
initType = 'pie', // graph types ('pie', 'pie3D', 'line', 'area', 'vbar', 'vstack', 'hbar' or 'hstack')
|
||||
chartTitle = 'Company Performance',
|
||||
axisTitle = 'Year',
|
||||
width = 900,
|
||||
height = 500,
|
||||
// extra data processing
|
||||
processor = function(data) {
|
||||
// console.log(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
// don't change anything below, unless you want to remove some types; modify styles and/or font-awesome icons
|
||||
types = {
|
||||
pie3D : { in3D: true, maxCol: 2, stack: false, type: 'pie', titleStyle: { color: '#333' }, icon: 'fa-cube' },
|
||||
pie : { in3D: false, maxCol: 2, stack: false, type: 'pie', titleStyle: { color: '#333' }, icon: 'fa-pie-chart' },
|
||||
line : { in3D: false, maxCol: 99,stack: false, type: 'line', titleStyle: { color: '#333' }, icon: 'fa-line-chart' },
|
||||
area : { in3D: false, maxCol: 5, stack: false, type: 'area', titleStyle: { color: '#333' }, icon: 'fa-area-chart' },
|
||||
vbar : { in3D: false, maxCol: 5, stack: false, type: 'vbar', titleStyle: { color: '#333' }, icon: 'fa-bar-chart' },
|
||||
vstack : { in3D: false, maxCol: 5, stack: true, type: 'vbar', titleStyle: { color: '#333' }, icon: 'fa-tasks fa-rotate-90' },
|
||||
hbar : { in3D: false, maxCol: 5, stack: false, type: 'hbar', titleStyle: { color: '#333' }, icon: 'fa-align-left' },
|
||||
hstack : { in3D: false, maxCol: 5, stack: true, type: 'hbar', titleStyle: { color: '#333' }, icon: 'fa-tasks fa-rotate-180' }
|
||||
},
|
||||
/* internal variables */
|
||||
settings = {
|
||||
table : $table,
|
||||
chart : $chart[0],
|
||||
chartTitle : chartTitle,
|
||||
axisTitle : axisTitle,
|
||||
type : initType,
|
||||
processor : processor
|
||||
},
|
||||
drawChart = function() {
|
||||
if (!$table[0].config) { return; }
|
||||
var options, chart, numofcols, data,
|
||||
s = settings,
|
||||
t = types[s.type],
|
||||
obj = s.chart,
|
||||
rawdata = $table[0].config.chart.data;
|
||||
if ( $.isFunction( s.processor ) ) {
|
||||
rawdata = s.processor( rawdata );
|
||||
}
|
||||
if ( rawdata.length < 2 ) {
|
||||
return;
|
||||
}
|
||||
data = google.visualization.arrayToDataTable( rawdata );
|
||||
|
||||
numofcols = rawdata[1].length;
|
||||
if (numofcols > t.maxCol) {
|
||||
// default to line chart if too many columns selected
|
||||
t = types['line'];
|
||||
}
|
||||
|
||||
options = {
|
||||
title: s.chartTitle,
|
||||
chart: {
|
||||
title: s.chartTitle
|
||||
},
|
||||
hAxis: {
|
||||
title: s.axisTitle,
|
||||
titleTextStyle: t.titleStyle
|
||||
},
|
||||
vAxis: {},
|
||||
is3D: t.in3D,
|
||||
isStacked: t.stack,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
|
||||
if (t.type == 'vbar' && !t.stack) {
|
||||
chart = new google.charts.Bar(obj);
|
||||
} else if (t.type == 'vbar') {
|
||||
chart = new google.visualization.ColumnChart(obj);
|
||||
} else if (t.type == 'hbar') {
|
||||
options.hAxis = {};
|
||||
options.vAxis = {
|
||||
title: s.axisTitle,
|
||||
titleTextStyle: t.titleStyle,
|
||||
minValue: 0
|
||||
};
|
||||
chart = new google.visualization.BarChart(obj);
|
||||
} else if (t.type == 'area') {
|
||||
chart = new google.visualization.AreaChart(obj);
|
||||
} else if (t.type == 'line') {
|
||||
chart = new google.charts.Line(obj);
|
||||
} else {
|
||||
chart = new google.visualization.PieChart(obj);
|
||||
}
|
||||
chart.draw(data, options);
|
||||
};
|
||||
|
||||
$('#chartSelect').change(function() {
|
||||
$('#chart-container').slideToggle( $(this).is(':checked') );
|
||||
drawChart();
|
||||
});
|
||||
|
||||
$icons.click(function(e) {
|
||||
if ( $(e.target).hasClass('disabled') ) {
|
||||
return true;
|
||||
}
|
||||
$icons.removeClass('active');
|
||||
var $t = $(this).addClass('active');
|
||||
$.each(types, function(i, v){
|
||||
if ($t.hasClass(v.icon)) {
|
||||
settings.type = i;
|
||||
}
|
||||
});
|
||||
drawChart();
|
||||
});
|
||||
|
||||
$rowType.on('change', function(){
|
||||
$table[0].config.widgetOptions.chart_incRows = $rowType.filter(':checked').attr('data-type');
|
||||
// update data, then draw new chart
|
||||
$table.trigger('chartData');
|
||||
drawChart();
|
||||
});
|
||||
|
||||
$table.on('columnUpdate pagerComplete', function(e) {
|
||||
var table = this,
|
||||
c = table.config,
|
||||
t = types['pie'],
|
||||
max = t && t.maxCol || 2;
|
||||
setTimeout(function() {
|
||||
if (table.hasInitialized) {
|
||||
$table.trigger('chartData');
|
||||
drawChart();
|
||||
// update chart icons
|
||||
if (typeof c.chart !== 'undefined') {
|
||||
var cols = c.chart.data[0].length;
|
||||
if (cols > max) {
|
||||
$bar.find('.fa-cube, .fa-pie-chart').addClass('disabled');
|
||||
if ($bar.find('.fa-cube, .fa-pie-chart').hasClass('active')) {
|
||||
$bar.find('.fa-cube, .fa-pie-chart').removeClass('active');
|
||||
$bar.find('.fa-line-chart').addClass('active');
|
||||
}
|
||||
} else {
|
||||
$bar.find('.fa-cube, .fa-pie-chart').removeClass('disabled');
|
||||
if (settings.type == 'pie') {
|
||||
$bar.find('.active').removeClass('active');
|
||||
$bar.find( settings.in3D ? '.fa-cube' : '.fa-pie-chart' ).addClass('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 10);
|
||||
});
|
||||
|
||||
$table
|
||||
.tablesorter({
|
||||
theme: 'blue',
|
||||
sortList: [[0, 0]],
|
||||
widgets: ['pager', 'zebra', 'filter', 'cssStickyHeaders', 'columnSelector', 'chart'],
|
||||
widgetOptions: {
|
||||
columnSelector_container: '#columnSelector',
|
||||
cssStickyHeaders_filteredToTop: false,
|
||||
pager_selectors: { container: '#pager' },
|
||||
pager_output: 'Showing {startRow} to {endRow} of {filteredRows} results',
|
||||
pager_size: 5,
|
||||
chart_incRows: 'f',
|
||||
chart_useSelector: true,
|
||||
chart_hideTable: false
|
||||
}
|
||||
});
|
||||
|
||||
});</script>
|
||||
|
||||
<script>
|
||||
$(function(){
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -470,6 +470,7 @@
|
||||
<li><span class="label label-info">Beta</span> <a href="example-widget-align-character.html">Align Character Widget</a> (<span class="version">v2.15.8</span>).</li>
|
||||
<li><a href="example-widget-build-table.html">Build Table Widget</a> (<span class="version">v2.11</span>; <span class="version updated">v2.16</span>).</li>
|
||||
|
||||
<li><span class="label label-info">Beta</span> <a href="example-widget-chart.html">Chart Widget</a> (<span class="version">v2.18.5</span>).</li>
|
||||
<li><span class="results">†</span> <a href="example-widget-columns.html">Columns Highlight widget</a> (v2.0.17)</li>
|
||||
<li><span class="label label-info">Beta</span> <a href="example-widget-column-selector.html">Column Selector widget</a> (<span class="version">v2.15</span>; <span class="version updated">v2.18.5</span>).</li>
|
||||
<li><a href="example-widget-editable.html">Content Editable widget</a> (v2.9; <span class="version updated">v2.18.0</span>).</li>
|
||||
|
@ -1,200 +1,276 @@
|
||||
/* Chart widget (beta) for TableSorter 1/27/2015 (v2.19.0)
|
||||
/* Chart widget (beta) for TableSorter 2/7/2015 (v2.19.0)
|
||||
* Requires tablesorter v2.8+ and jQuery 1.7+
|
||||
*/
|
||||
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global jQuery: false */
|
||||
|
||||
;(function($){
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var ts = $.tablesorter,
|
||||
var ts = $.tablesorter,
|
||||
|
||||
chart = ts.chart = {
|
||||
// temp variables
|
||||
chart_cols = [],
|
||||
chart_headers = [],
|
||||
// google charts
|
||||
chart_rows = [],
|
||||
chart_data = [],
|
||||
// highcharts
|
||||
chart_categories = [],
|
||||
chart_series = [],
|
||||
// fusioncharts
|
||||
chart_category = [],
|
||||
chart_dataset = [],
|
||||
|
||||
event: 'chartData',
|
||||
chart = ts.chart = {
|
||||
|
||||
chartdata: [],
|
||||
cols: [],
|
||||
headers: [],
|
||||
rows: [],
|
||||
// regex used to strip out non-digit values before sending
|
||||
// the string to the $.tablesorter.formatFloat function
|
||||
nonDigit : /[^\d,.\-()]/g,
|
||||
|
||||
init: function(c, wo) {
|
||||
c.$table
|
||||
.off(chart.event)
|
||||
.on(chart.event, function() {
|
||||
chart.getCols(c, wo);
|
||||
chart.getData(c, wo);
|
||||
});
|
||||
},
|
||||
|
||||
getCols: function(c, wo) {
|
||||
chart.cols = [];
|
||||
|
||||
for(var i = 0; i < c.columns; i++) {
|
||||
if (wo.chart_useSelector &&
|
||||
$.inArray('columnSelector', c.widgets) !== -1 &&
|
||||
c.selector.auto === false
|
||||
) {
|
||||
if ((c.selector.states[i] === true && $.inArray(i, wo.chart_ignoreColumns) === -1) ||
|
||||
i == wo.chart_labelCol ||
|
||||
i == wo.chart_sort[0][0]
|
||||
) {
|
||||
chart.cols.push(i);
|
||||
}
|
||||
} else {
|
||||
if ($.inArray(i, wo.chart_ignoreColumns) === -1 ||
|
||||
i == wo.chart_labelCol ||
|
||||
i == wo.chart_sort[0][0]
|
||||
) {
|
||||
chart.cols.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getData: function(c, wo) {
|
||||
chart.getHeaders(c, wo);
|
||||
chart.getRows(c, wo);
|
||||
|
||||
chart.chartdata = [
|
||||
chart.headers
|
||||
];
|
||||
|
||||
$.each(chart.rows, function(k, row) {
|
||||
chart.chartdata.push(row);
|
||||
});
|
||||
|
||||
c.chart = {
|
||||
data: chart.chartdata
|
||||
};
|
||||
},
|
||||
|
||||
getHeaders: function(c, wo) {
|
||||
chart.headers = [];
|
||||
chart.headers.push(c.headerContent[wo.chart_labelCol]);
|
||||
$.each(chart.cols, function(k, col) {
|
||||
if (col == wo.chart_labelCol) {
|
||||
return true;
|
||||
}
|
||||
|
||||
chart.headers.push(c.headerContent[col]);
|
||||
});
|
||||
},
|
||||
|
||||
getRows: function(c, wo) {
|
||||
var $table = c.$table;
|
||||
// the cache may not have a zero index if there are any
|
||||
// "info-only" tbodies above the main tbody
|
||||
var cache = c.cache[0].normalized;
|
||||
var rows = [];
|
||||
chart.rows = [];
|
||||
|
||||
$.each(cache, function(k, v) {
|
||||
var $tr = v[c.columns].$row;
|
||||
var cells = $tr.find('td');
|
||||
var row = [];
|
||||
if ((wo.chart_incRows == 'visible' && $tr.is(':visible')) ||
|
||||
(wo.chart_incRows == 'filtered' && !$tr.hasClass(wo.filter_filteredRow || 'filtered')) ||
|
||||
(wo.chart_incRows != 'visible' && wo.chart_incRows != 'filtered')
|
||||
) {
|
||||
// Add all cols (don't mess up indx for sorting)
|
||||
for(var i = 0; i < c.columns; i++) {
|
||||
if ($.inArray(k, wo.chart_parsed) !== -1) {
|
||||
row.push(v[i]);
|
||||
} else {
|
||||
row.push($(cells[i]).text().trim());
|
||||
init: function(c, wo) {
|
||||
c.$table
|
||||
.off(wo.chart_event)
|
||||
.on(wo.chart_event, function() {
|
||||
if (this.hasInitialized) {
|
||||
// refresh "c" variable in case options are updated dynamically
|
||||
var c = this.config;
|
||||
chart.getCols(c, c.widgetOptions);
|
||||
chart.getData(c, c.widgetOptions);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
rows.push(row);
|
||||
}
|
||||
});
|
||||
getCols: function(c, wo) {
|
||||
var i;
|
||||
chart_cols = [];
|
||||
chart_series = [];
|
||||
chart_dataset = [];
|
||||
|
||||
// sort based on chart_sort
|
||||
rows.sort(function(a, b) {
|
||||
if (wo.chart_sort[0][1] == 1) {
|
||||
return $.tablesorter.sortNatural(b[wo.chart_sort[0][0]], a[wo.chart_sort[0][0]]);
|
||||
}
|
||||
|
||||
return $.tablesorter.sortNatural(a[wo.chart_sort[0][0]], b[wo.chart_sort[0][0]]);
|
||||
});
|
||||
|
||||
$.each(rows, function(kk, vv) {
|
||||
var row = [];
|
||||
var label = vv[wo.chart_labelCol];
|
||||
|
||||
row.push(String(label));
|
||||
|
||||
$.each(vv, function(k, cell) {
|
||||
if (k == wo.chart_labelCol) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var thiscell = false;
|
||||
|
||||
if (wo.chart_useSelector &&
|
||||
$.inArray('columnSelector', c.widgets) !== -1 &&
|
||||
c.selector.auto === false
|
||||
) {
|
||||
if (c.selector.states[k] === true &&
|
||||
$.inArray(k, wo.chart_ignoreColumns) === -1
|
||||
) {
|
||||
thiscell = cell;
|
||||
for ( i = 0; i < c.columns; i++ ) {
|
||||
if ( wo.chart_useSelector && ts.hasWidget( c.table, 'columnSelector' ) && !c.selector.auto ) {
|
||||
if ( ( c.selector.states[i] && $.inArray(i, wo.chart_ignoreColumns) < 0 ) ||
|
||||
i === wo.chart_labelCol || i === wo.chart_sort[0][0] ) {
|
||||
chart_cols.push(i);
|
||||
}
|
||||
} else {
|
||||
if ($.inArray(k, wo.chart_ignoreColumns) === -1) {
|
||||
thiscell = cell;
|
||||
if ( $.inArray(i, wo.chart_ignoreColumns) < 0 || i === wo.chart_labelCol || i === wo.chart_sort[0][0] ) {
|
||||
chart_cols.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
if (thiscell !== false) {
|
||||
if (wo.chart_layout[row.length] == 'string') {
|
||||
row.push(String(thiscell));
|
||||
} else {
|
||||
row.push(parseFloat(thiscell));
|
||||
getData: function(c, wo) {
|
||||
chart.getHeaders(c, wo);
|
||||
chart.getRows(c, wo);
|
||||
|
||||
/* == Google data ==
|
||||
array of arrays (Google charts)
|
||||
[
|
||||
[ "Year", "Sales", "Expenses" ],
|
||||
[ "2004", 1000, 400 ],
|
||||
[ "2005", 1170, 460 ],
|
||||
[ "2006", 660, 1120 ],
|
||||
[ "2007", 1030, 540 ]
|
||||
]
|
||||
|
||||
== Highcharts ==
|
||||
categories -> [ '2004', '2005', '2006', '2007' ]
|
||||
series -> [{
|
||||
name: 'Sales',
|
||||
data: [ 1000, 1170, 660, 1030 ]
|
||||
}, {
|
||||
name: 'Expenses',
|
||||
data: [ 400, 460, 1120, 540 ]
|
||||
}]
|
||||
|
||||
== Fusioncharts
|
||||
"categories": [{
|
||||
"category": [
|
||||
{"label": "2004"},
|
||||
{"label": "2005"},
|
||||
{"label": "2006"},
|
||||
{"label": "2007"}
|
||||
]
|
||||
}],
|
||||
"dataset": [
|
||||
{
|
||||
"seriesname": "Sales",
|
||||
"data": [
|
||||
{"value": "1000"},
|
||||
{"value": "1170"},
|
||||
{"value": "660"},
|
||||
{"value": "1030"}
|
||||
]
|
||||
},{
|
||||
"seriesname": "Expenses",
|
||||
"data": [
|
||||
{"value": "400"},
|
||||
{"value": "600"},
|
||||
{"value": "1120"},
|
||||
{"value": "540"}
|
||||
]
|
||||
}
|
||||
]
|
||||
*/
|
||||
|
||||
chart_data = [ chart_headers ];
|
||||
$.each(chart_rows, function(k, row) {
|
||||
chart_data.push(row);
|
||||
});
|
||||
|
||||
c.chart = {
|
||||
// google
|
||||
data: chart_data,
|
||||
// highcharts
|
||||
categories: chart_categories,
|
||||
series: chart_series,
|
||||
// FusionCharts
|
||||
category: chart_category,
|
||||
dataset: chart_dataset
|
||||
};
|
||||
},
|
||||
|
||||
getHeaders: function(c, wo) {
|
||||
var text;
|
||||
chart_headers = [];
|
||||
chart_series = [];
|
||||
chart_dataset = [];
|
||||
chart_headers.push( c.headerContent[wo.chart_labelCol] );
|
||||
$.each(chart_cols, function(k, col) {
|
||||
if (col === wo.chart_labelCol) {
|
||||
return true;
|
||||
}
|
||||
text = c.headerContent[col];
|
||||
chart_headers.push( text );
|
||||
chart_series.push( { name: text, data: [] } );
|
||||
chart_dataset.push( { seriesname: text, data: [] } );
|
||||
});
|
||||
},
|
||||
|
||||
getRows: function(c, wo) {
|
||||
// the cache may not have a zero index if there are any "info-only" tbodies above the main tbody
|
||||
var cache = c.cache[0].normalized,
|
||||
rows = [];
|
||||
chart_rows = [];
|
||||
chart_categories = [];
|
||||
chart_category = [];
|
||||
|
||||
$.each(cache, function(indx, rowVal) {
|
||||
var i, txt,
|
||||
$tr = rowVal[c.columns].$row,
|
||||
$cells = $tr.children('th,td'),
|
||||
row = [];
|
||||
if (
|
||||
(/v/i.test(wo.chart_incRows) && $tr.is(':visible')) ||
|
||||
(/f/i.test(wo.chart_incRows) && !$tr.hasClass(wo.filter_filteredRow || 'filtered')) ||
|
||||
(!/(v|f)/i.test(wo.chart_incRows))
|
||||
) {
|
||||
// Add all cols (don't mess up indx for sorting)
|
||||
for (i = 0; i < c.columns; i++) {
|
||||
if ( $.inArray(indx, wo.chart_parsed) >= 0 ) {
|
||||
row.push( rowVal[i] );
|
||||
} else {
|
||||
txt = $cells[i].getAttribute( c.textAttribute ) || $cells[i].textContent || $cells.eq(i).text();
|
||||
row.push( $.trim( txt ) );
|
||||
}
|
||||
}
|
||||
rows.push(row);
|
||||
}
|
||||
});
|
||||
|
||||
chart.rows.push(row);
|
||||
});
|
||||
},
|
||||
// sort based on chart_sort
|
||||
rows.sort(function(a, b) {
|
||||
if ( wo.chart_sort[0][1] === 1 ) {
|
||||
return ts.sortNatural( b[wo.chart_sort[0][0]], a[wo.chart_sort[0][0]] );
|
||||
}
|
||||
return ts.sortNatural( a[wo.chart_sort[0][0]], b[wo.chart_sort[0][0]] );
|
||||
});
|
||||
|
||||
remove: function(c) {
|
||||
c.$table.off(chart.event);
|
||||
}
|
||||
};
|
||||
$.each(rows, function(i, rowVal) {
|
||||
var value,
|
||||
objIndex = 0,
|
||||
row = [],
|
||||
label = rowVal[wo.chart_labelCol];
|
||||
|
||||
ts.addWidget({
|
||||
id: 'chart',
|
||||
options: {
|
||||
// all, visible or filtered
|
||||
chart_incRows: 'filtered',
|
||||
// prefer columnSelector for ignoreColumns
|
||||
chart_useSelector: false,
|
||||
// columns to ignore [0, 1,... ] (zero-based index)
|
||||
chart_ignoreColumns: [],
|
||||
// Use parsed data instead of cell.text()
|
||||
chart_parsed: [],
|
||||
// data output layout, int is default
|
||||
chart_layout: {
|
||||
// first element is a string, all others will be float
|
||||
0: 'string'
|
||||
row.push( '' + label );
|
||||
|
||||
$.each(rowVal, function(indx, cellValue) {
|
||||
var tempVal;
|
||||
if (indx === wo.chart_labelCol) {
|
||||
chart_categories.push( cellValue );
|
||||
chart_category.push({ 'label': cellValue });
|
||||
return true;
|
||||
}
|
||||
value = false;
|
||||
if ( wo.chart_useSelector && ts.hasWidget( c.table, 'columnSelector' ) && !c.selector.auto ) {
|
||||
if ( c.selector.states[indx] && $.inArray(indx, wo.chart_ignoreColumns) < 0 ) {
|
||||
value = '' + cellValue;
|
||||
}
|
||||
} else {
|
||||
if ($.inArray(indx, wo.chart_ignoreColumns) < 0) {
|
||||
value = '' + cellValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (value !== false) {
|
||||
if ( /s/i.test( '' + wo.chart_layout[row.length] ) ) {
|
||||
row.push( value );
|
||||
chart_series[objIndex].data.push( value );
|
||||
chart_dataset[objIndex].data.push( value );
|
||||
} else {
|
||||
// using format float, after stripping out all non-digit values
|
||||
tempVal = ts.formatFloat( value.replace( chart.nonDigit, '' ), c.table );
|
||||
tempVal = isNaN(tempVal) ? value : tempVal;
|
||||
// if tempVal ends up being an empty string, fall back to value
|
||||
row.push( tempVal );
|
||||
chart_series[objIndex].data.push( tempVal );
|
||||
chart_dataset[objIndex].data.push( { value : tempVal } );
|
||||
}
|
||||
objIndex++;
|
||||
}
|
||||
});
|
||||
chart_rows.push(row);
|
||||
});
|
||||
},
|
||||
// Set the label column
|
||||
chart_labelCol: 0,
|
||||
// data sort, shoudl always be first row, might want [[0,1]]
|
||||
chart_sort: [[0,0]]
|
||||
},
|
||||
|
||||
init: function(table, thisWidget, c, wo) {
|
||||
chart.init(c, wo);
|
||||
},
|
||||
remove: function(c) {
|
||||
c.$table.off(chart.event);
|
||||
}
|
||||
|
||||
remove: function(table, c, wo) {
|
||||
chart.remove(c);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ts.addWidget({
|
||||
id: 'chart',
|
||||
options: {
|
||||
// (a)ll, (v)isible or (f)iltered - only the first letter is needed
|
||||
chart_incRows: 'filtered',
|
||||
// prefer columnSelector for ignoreColumns
|
||||
chart_useSelector: false,
|
||||
// columns to ignore [0, 1,... ] (zero-based index)
|
||||
chart_ignoreColumns: [],
|
||||
// Use parsed data instead of cell.text()
|
||||
chart_parsed: [],
|
||||
// data output layout, float is default
|
||||
chart_layout: {
|
||||
// first element is a string, all others will be float
|
||||
0: 'string'
|
||||
},
|
||||
// Set the label column
|
||||
chart_labelCol: 0,
|
||||
// data sort, should always be first row, might want [[0,1]]
|
||||
chart_sort: [[0,0]],
|
||||
// event to trigger get updated data
|
||||
chart_event: 'chartData'
|
||||
},
|
||||
|
||||
init: function(table, thisWidget, c, wo) {
|
||||
chart.init(c, wo);
|
||||
},
|
||||
|
||||
remove: function(table, c, wo) {
|
||||
chart.remove(c);
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
Loading…
Reference in New Issue
Block a user