diff --git a/Documentation.html b/Documentation.html
index d7c76e16a4..8872e5e9a2 100644
--- a/Documentation.html
+++ b/Documentation.html
@@ -4410,13 +4410,43 @@ chmod o+rwx tmp
+ 6.31 How do I create a relation in designer?
To select relation, click :
The display column is shown in pink. To set/unset a column as the display column, click the "Choose column to display" icon, then click on the appropriate column name.
+
+
+ Zoom search feature is an alternative to table search feature. It allows you to explore
+ a table by representing its data in a scatter plot. You can locate this feature by selecting
+ a table and clicking the 'Search' tab. One of the sub-tab in the 'Table Search' page is
+ 'Zoom Search'.
+
+ Consider the table REL_persons in
+ FAQ 6.6 for an example. To use zoom search, two columns need to be selected,
+ for example, id and town_code. The id values will be represented on one axis and town_code
+ values on the other axis. Each row will be represented as a point in a scatter plot based
+ on its id and town_code. You can include two additional search criteria apart from the two
+ fields to display.
+
+ You can choose which field should be displayed as label for each point. If a display
+ column has been set for the table (see FAQ 6.7), it is taken as the label unless you specify otherwise.
+ You can also select the maximum number of rows you want to be displayed in the plot by
+ specifing it in the 'Max rows to plot' field. Once you have decided over your criteria,
+ click 'Go' to display the plot.
+
+ After the plot is generated, you can use the mousewheel to zoom in and out of the plot.
+ In addition, panning feature is enabled to navigate through the plot. You can zoom-in to
+ a certail level of detail and use panning to locate your area of interest. Clicking on a
+ point opens a dialogue box, displaying field values of the data row represented by the point.
+ You can edit the values if required and and click on submit to issue an update query. Basic
+ instructions on how to use can be viewed by clicking the 'How to use?' link located just above
+ the plot.
+
phpMyAdmin project
diff --git a/js/messages.php b/js/messages.php
index 7bb7bd3fa1..8a606dc6eb 100644
--- a/js/messages.php
+++ b/js/messages.php
@@ -265,7 +265,9 @@ $js_messages['strDisplayHelp'] = '- '
. '
- '
. __('Hovering over a point will show its label.')
. '
- '
- . __('Drag and select an area in the plot to zoom into it.')
+ . __('Use mousewheel to zoom in or out of the plot.')
+ . '
- '
+ . __('Click and drag the mouse to navigate the plot.')
. '
- '
. __('Click reset zoom link to come back to original state.')
. '
- '
diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js
index 796b543ba2..e773175d7a 100644
--- a/js/tbl_zoom_plot.js
+++ b/js/tbl_zoom_plot.js
@@ -35,7 +35,7 @@ Array.min = function (array) {
/**
** Checks if a string contains only numeric value
- ** @param n: String (to be checked)
+ ** @param n: String (to be checked)
**/
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
@@ -43,7 +43,7 @@ function isNumeric(n) {
/**
** Checks if an object is empty
- ** @param n: Object (to be checked)
+ ** @param n: Object (to be checked)
**/
function isEmpty(obj) {
var name;
@@ -59,15 +59,15 @@ function isEmpty(obj) {
** @param type String Field type(datetime/timestamp/time/date)
**/
function getDate(val,type) {
- if (type.toString().search(/datetime/i) != -1 || type.toString().search(/timestamp/i) != -1) {
- return Highcharts.dateFormat('%Y-%m-%e %H:%M:%S', val)
- }
- else if (type.toString().search(/time/i) != -1) {
- return Highcharts.dateFormat('%H:%M:%S', val + 19800000)
- }
+ if(type.toString().search(/datetime/i) != -1 || type.toString().search(/timestamp/i) != -1) {
+ return Highcharts.dateFormat('%Y-%m-%e %H:%M:%S', val)
+ }
+ else if(type.toString().search(/time/i) != -1) {
+ return Highcharts.dateFormat('%H:%M:%S', val)
+ }
else if (type.toString().search(/date/i) != -1) {
return Highcharts.dateFormat('%Y-%m-%e', val)
- }
+ }
}
/**
@@ -76,30 +76,30 @@ function getDate(val,type) {
** @param type Sring Field type(datetime/timestamp/time/date)
**/
function getTimeStamp(val,type) {
- if (type.toString().search(/datetime/i) != -1 || type.toString().search(/timestamp/i) != -1) {
- return getDateFromFormat(val,'yyyy-MM-dd HH:mm:ss', val)
- }
- else if (type.toString().search(/time/i) != -1) {
- return getDateFromFormat('1970-01-01 ' + val,'yyyy-MM-dd HH:mm:ss')
- }
+ if(type.toString().search(/datetime/i) != -1 || type.toString().search(/timestamp/i) != -1) {
+ return getDateFromFormat(val,'yyyy-MM-dd HH:mm:ss', val)
+ }
+ else if(type.toString().search(/time/i) != -1) {
+ return getDateFromFormat('1970-01-01 ' + val,'yyyy-MM-dd HH:mm:ss')
+ }
else if (type.toString().search(/date/i) != -1) {
- return getDateFromFormat(val,'yyyy-MM-dd')
- }
+ return getDateFromFormat(val,'yyyy-MM-dd')
+ }
}
/**
** Classifies the field type into numeric,timeseries or text
** @param field: field type (as in database structure)
- **/
+ **/
function getType(field) {
- if (field.toString().search(/int/i) != -1 || field.toString().search(/decimal/i) != -1 || field.toString().search(/year/i) != -1)
- return 'numeric';
- else if (field.toString().search(/time/i) != -1 || field.toString().search(/date/i) != -1)
- return 'time';
- else
- return 'text';
+ if(field.toString().search(/int/i) != -1 || field.toString().search(/decimal/i) != -1 || field.toString().search(/year/i) != -1)
+ return 'numeric';
+ else if(field.toString().search(/time/i) != -1 || field.toString().search(/date/i) != -1)
+ return 'time';
+ else
+ return 'text';
}
-/**
+/**
** Converts a categorical array into numeric array
** @param array categorical values array
**/
@@ -121,6 +121,51 @@ function scrollToChart() {
$('html,body').animate({scrollTop: x}, 500);
}
+/**
+ ** Handlers for panning feature
+ **/
+function includePan(currentChart) {
+ var mouseDown;
+ var lastX;
+ var lastY;
+ var chartWidth = $('#resizer').width() - 3;
+ var chartHeight = $('#resizer').height() - 20;
+ $('#querychart').mousedown(function() {
+ mouseDown = 1;
+ });
+
+ $('#querychart').mouseup(function() {
+ mouseDown = 0;
+ });
+ $('#querychart').mousemove(function(e) {
+ if (mouseDown == 1) {
+ if (e.pageX > lastX) {
+ var xExtremes = currentChart.xAxis[0].getExtremes();
+ var diff = (e.pageX - lastX) * (xExtremes.max - xExtremes.min) / chartWidth;
+ currentChart.xAxis[0].setExtremes(xExtremes.min - diff, xExtremes.max - diff);
+ }
+ else if (e.pageX < lastX) {
+ var xExtremes = currentChart.xAxis[0].getExtremes();
+ var diff = (lastX - e.pageX) * (xExtremes.max - xExtremes.min) / chartWidth;
+ currentChart.xAxis[0].setExtremes(xExtremes.min + diff, xExtremes.max + diff);
+ }
+
+ if (e.pageY > lastY) {
+ var yExtremes = currentChart.yAxis[0].getExtremes();
+ var ydiff = 1.0 * (e.pageY - lastY) * (yExtremes.max - yExtremes.min) / chartHeight;
+ currentChart.yAxis[0].setExtremes(yExtremes.min + ydiff, yExtremes.max + ydiff);
+ }
+ else if (e.pageY < lastY) {
+ var yExtremes = currentChart.yAxis[0].getExtremes();
+ var ydiff = 1.0 * (lastY - e.pageY) * (yExtremes.max - yExtremes.min) / chartHeight;
+ currentChart.yAxis[0].setExtremes(yExtremes.min - ydiff, yExtremes.max - ydiff);
+ }
+ }
+ lastX = e.pageX;
+ lastY = e.pageY;
+ });
+}
+
$(document).ready(function() {
/**
@@ -131,7 +176,7 @@ $(document).ready(function() {
cache: 'false'
});
- var cursorMode = ($("input[name='mode']:checked").val() == 'edit') ? 'crosshair' : 'pointer';
+ var cursorMode = ($("input[name='mode']:checked").val() == 'edit') ? 'crosshair' : 'pointer';
var currentChart = null;
var currentData = null;
var xLabel = $('#tableid_0').val();
@@ -139,8 +184,12 @@ $(document).ready(function() {
var xType = $('#types_0').val();
var yType = $('#types_1').val();
var dataLabel = $('#dataLabel').val();
+ var lastX;
+ var lastY;
+ var zoomRatio = 1;
- // Get query result
+
+ // Get query result
var data = jQuery.parseJSON($('#querydata').html());
/**
@@ -164,16 +213,16 @@ $(document).ready(function() {
/**
* Input form validation
- **/
+ **/
$('#inputFormSubmitId').click(function() {
- if ($('#tableid_0').get(0).selectedIndex == 0 || $('#tableid_1').get(0).selectedIndex == 0)
- PMA_ajaxShowMessage(PMA_messages['strInputNull']);
- else if (xLabel == yLabel)
+ if ($('#tableid_0').get(0).selectedIndex == 0 || $('#tableid_1').get(0).selectedIndex == 0)
+ PMA_ajaxShowMessage(PMA_messages['strInputNull']);
+ else if (xLabel == yLabel)
PMA_ajaxShowMessage(PMA_messages['strSameInputs']);
});
/**
- ** Prepare a div containing a link, otherwise it's incorrectly displayed
+ ** Prepare a div containing a link, otherwise it's incorrectly displayed
** after a couple of clicks
**/
$('')
@@ -191,177 +240,177 @@ $(document).ready(function() {
} else {
$link.text(PMA_messages['strHideSearchCriteria']);
}
- // avoid default click action
- return false;
- });
-
- /**
+ // avoid default click action
+ return false;
+ });
+
+ /**
** Set dialog properties for the data display form
**/
$("#dataDisplay").dialog({
autoOpen: false,
- title: 'Data point content',
+ title: 'Data point content',
modal: false, //false otherwise other dialogues like timepicker may not function properly
height: $('#dataDisplay').height() + 80,
width: $('#dataDisplay').width() + 80
});
/*
- * Handle submit of zoom_display_form
+ * Handle submit of zoom_display_form
*/
-
+
$("#submitForm").click(function(event) {
-
+
//Prevent default submission of form
event.preventDefault();
-
- //Find changed values by comparing form values with selectedRow Object
- var newValues = new Array();//Stores the values changed from original
+
+ //Find changed values by comparing form values with selectedRow Object
+ var newValues = new Array();//Stores the values changed from original
var it = 4;
var xChange = false;
var yChange = false;
- for (key in selectedRow) {
- if (key != 'where_clause'){
- var oldVal = selectedRow[key];
- var newVal = ($('#fields_null_id_' + it).attr('checked')) ? null : $('#fieldID_' + it).val();
- if (oldVal != newVal){
- selectedRow[key] = newVal;
- newValues[key] = newVal;
- if (key == xLabel) {
- xChange = true;
- data[currentData][xLabel] = newVal;
- }
- else if (key == yLabel) {
- yChange = true;
- data[currentData][yLabel] = newVal;
- }
- }
- }
- it++
- }//End data update
-
- //Update the chart series and replot
+ for (key in selectedRow) {
+ if (key != 'where_clause'){
+ var oldVal = selectedRow[key];
+ var newVal = ($('#fields_null_id_' + it).attr('checked')) ? null : $('#fieldID_' + it).val();
+ if (oldVal != newVal){
+ selectedRow[key] = newVal;
+ newValues[key] = newVal;
+ if(key == xLabel) {
+ xChange = true;
+ data[currentData][xLabel] = newVal;
+ }
+ else if(key == yLabel) {
+ yChange = true;
+ data[currentData][yLabel] = newVal;
+ }
+ }
+ }
+ it++
+ }//End data update
+
+ //Update the chart series and replot
if (xChange || yChange) {
- var newSeries = new Array();
- newSeries[0] = new Object();
+ var newSeries = new Array();
+ newSeries[0] = new Object();
newSeries[0].marker = {
symbol: 'circle'
};
- //Logic similar to plot generation, replot only if xAxis changes or yAxis changes. Code includes a lot of checks so as to replot only when necessary
- if (xChange) {
- xCord[currentData] = selectedRow[xLabel];
- if (xType == 'numeric') {
- currentChart.series[0].data[currentData].update({ x : selectedRow[xLabel] });
- currentChart.xAxis[0].setExtremes(Array.min(xCord) - 6,Array.max(xCord) + 6);
+ //Logic similar to plot generation, replot only if xAxis changes or yAxis changes. Code includes a lot of checks so as to replot only when necessary
+ if(xChange) {
+ xCord[currentData] = selectedRow[xLabel];
+ if(xType == 'numeric') {
+ currentChart.series[0].data[currentData].update({ x : selectedRow[xLabel] });
+ currentChart.xAxis[0].setExtremes(Array.min(xCord) - 6,Array.max(xCord) + 6);
}
- else if (xType == 'time') {
- currentChart.series[0].data[currentData].update({ x : getTimeStamp(selectedRow[xLabel],$('#types_0').val())});
- }
- else {
- var tempX = getCord(xCord);
- var tempY = getCord(yCord);
- var i = 0;
- newSeries[0].data = new Array();
- xCord = tempX[2];
- yCord = tempY[2];
+ else if(xType == 'time') {
+ currentChart.series[0].data[currentData].update({ x : getTimeStamp(selectedRow[xLabel],$('#types_0').val())});
+ }
+ else {
+ var tempX = getCord(xCord);
+ var tempY = getCord(yCord);
+ var i = 0;
+ newSeries[0].data = new Array();
+ xCord = tempX[2];
+ yCord = tempY[2];
- $.each(data,function(key,value) {
- if (yType != 'text')
- newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: value[yLabel], marker: {fillColor: colorCodes[i % 8]} , id: i } );
- else
+ $.each(data,function(key,value) {
+ if(yType != 'text')
+ newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: value[yLabel], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+ else
newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
- i++;
+ i++;
});
- currentSettings.xAxis.labels = { formatter : function() {
- if (tempX[1][this.value] && tempX[1][this.value].length > 10)
- return tempX[1][this.value].substring(0,10)
- else
- return tempX[1][this.value];
+ currentSettings.xAxis.labels = { formatter : function() {
+ if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+ return tempX[1][this.value].substring(0,10)
+ else
+ return tempX[1][this.value];
}
}
- currentSettings.series = newSeries;
+ currentSettings.series = newSeries;
currentChart = PMA_createChart(currentSettings);
- }
+ }
- }
- if (yChange) {
+ }
+ if(yChange) {
- yCord[currentData] = selectedRow[yLabel];
- if (yType == 'numeric') {
- currentChart.series[0].data[currentData].update({ y : selectedRow[yLabel] });
- currentChart.yAxis[0].setExtremes(Array.min(yCord) - 6,Array.max(yCord) + 6);
+ yCord[currentData] = selectedRow[yLabel];
+ if(yType == 'numeric') {
+ currentChart.series[0].data[currentData].update({ y : selectedRow[yLabel] });
+ currentChart.yAxis[0].setExtremes(Array.min(yCord) - 6,Array.max(yCord) + 6);
}
- else if (yType =='time') {
- currentChart.series[0].data[currentData].update({ y : getTimeStamp(selectedRow[yLabel],$('#types_1').val())});
- }
- else {
- var tempX = getCord(xCord);
- var tempY = getCord(yCord);
- var i = 0;
- newSeries[0].data = new Array();
- xCord = tempX[2];
- yCord = tempY[2];
+ else if(yType =='time') {
+ currentChart.series[0].data[currentData].update({ y : getTimeStamp(selectedRow[yLabel],$('#types_1').val())});
+ }
+ else {
+ var tempX = getCord(xCord);
+ var tempY = getCord(yCord);
+ var i = 0;
+ newSeries[0].data = new Array();
+ xCord = tempX[2];
+ yCord = tempY[2];
- $.each(data,function(key,value) {
- if (xType != 'text' )
+ $.each(data,function(key,value) {
+ if(xType != 'text' )
newSeries[0].data.push({ name: value[dataLabel], x: value[xLabel], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
- else
+ else
newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
- i++;
+ i++;
});
- currentSettings.yAxis.labels = { formatter : function() {
- if (tempY[1][this.value] && tempY[1][this.value].length > 10)
- return tempY[1][this.value].substring(0,10)
- else
- return tempY[1][this.value];
+ currentSettings.yAxis.labels = { formatter : function() {
+ if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+ return tempY[1][this.value].substring(0,10)
+ else
+ return tempY[1][this.value];
}
}
- currentSettings.series = newSeries;
- currentChart = PMA_createChart(currentSettings);
- }
- }
- currentChart.series[0].data[currentData].select();
+ currentSettings.series = newSeries;
+ currentChart = PMA_createChart(currentSettings);
+ }
+ }
+ currentChart.series[0].data[currentData].select();
}
- //End plot update
+ //End plot update
- //Generate SQL query for update
- if (!isEmpty(newValues)) {
+ //Generate SQL query for update
+ if (!isEmpty(newValues)) {
var sql_query = 'UPDATE `' + window.parent.table + '` SET ';
- for (key in newValues) {
- if (key != 'where_clause') {
- sql_query += '`' + key + '`=' ;
- var value = newValues[key];
- if (!isNumeric(value) && value != null)
- sql_query += '\'' + value + '\' ,';
- else
- sql_query += value + ' ,';
- }
- }
- sql_query = sql_query.substring(0, sql_query.length - 1);
- sql_query += ' WHERE ' + PMA_urldecode(data[currentData]['where_clause']);
-
- //Post SQL query to sql.php
- $.post('sql.php', {
+ for (key in newValues) {
+ if(key != 'where_clause') {
+ sql_query += '`' + key + '`=' ;
+ var value = newValues[key];
+ if(!isNumeric(value) && value != null)
+ sql_query += '\'' + value + '\' ,';
+ else
+ sql_query += value + ' ,';
+ }
+ }
+ sql_query = sql_query.substring(0, sql_query.length - 1);
+ sql_query += ' WHERE ' + PMA_urldecode(data[currentData]['where_clause']);
+
+ //Post SQL query to sql.php
+ $.post('sql.php', {
'token' : window.parent.token,
'db' : window.parent.db,
'ajax_request' : true,
'sql_query' : sql_query,
- 'inline_edit' : false
- }, function(data) {
- if (data.success == true) {
- $('#sqlqueryresults').html(data.sql_query);
- $("#sqlqueryresults").trigger('appendAnchor');
- }
- else
- PMA_ajaxShowMessage(data.error);
- })//End $.post
- }//End database update
- $("#dataDisplay").dialog("close");
- });//End submit handler
+ 'inline_edit' : false
+ }, function(data) {
+ if(data.success == true) {
+ $('#sqlqueryresults').html(data.sql_query);
+ $("#sqlqueryresults").trigger('appendAnchor');
+ }
+ else
+ PMA_ajaxShowMessage(data.error);
+ })//End $.post
+ }//End database update
+ $("#dataDisplay").dialog("close");
+ });//End submit handler
/*
* Generate plot using Highcharts
- */
+ */
if (data != null) {
$('#zoom_search_form')
@@ -369,87 +418,101 @@ $(document).ready(function() {
.hide();
$('#togglesearchformlink')
.text(PMA_messages['strShowSearchCriteria'])
- $('#togglesearchformdiv').show();
+ $('#togglesearchformdiv').show();
var selectedRow;
- var columnNames = new Array();
- var colorCodes = ['#FF0000','#00FFFF','#0000FF','#0000A0','#FF0080','#800080','#FFFF00','#00FF00','#FF00FF'];
- var series = new Array();
- var xCord = new Array();
- var yCord = new Array();
- var xCat = new Array();
- var yCat = new Array();
- var tempX, tempY;
- var it = 0;
+ var colorCodes = ['#FF0000','#00FFFF','#0000FF','#0000A0','#FF0080','#800080','#FFFF00','#00FF00','#FF00FF'];
+ var series = new Array();
+ var xCord = new Array();
+ var yCord = new Array();
+ var tempX, tempY;
+ var it = 0;
+ var xMax; // xAxis extreme max
+ var xMin; // xAxis extreme min
+ var yMax; // yAxis extreme max
+ var yMin; // yAxis extreme min
// Set the basic plot settings
var currentSettings = {
chart: {
- renderTo: 'querychart',
- type: 'scatter',
- zoomType: 'xy',
- width:$('#resizer').width() -3,
- height:$('#resizer').height()-20
+ renderTo: 'querychart',
+ type: 'scatter',
+ //zoomType: 'xy',
+ width:$('#resizer').width() -3,
+ height:$('#resizer').height()-20
+ },
+ credits: {
+ enabled: false
},
- credits: {
- enabled: false
- },
- exporting: { enabled: false },
+ exporting: { enabled: false },
label: { text: $('#dataLabel').val() },
- plotOptions: {
- series: {
- allowPointSelect: true,
+ plotOptions: {
+ series: {
+ allowPointSelect: true,
cursor: 'pointer',
- showInLegend: false,
+ showInLegend: false,
dataLabels: {
- enabled: false
+ enabled: false,
},
- point: {
+ point: {
events: {
click: function() {
- var id = this.id;
- var fid = 4;
- currentData = id;
- // Make AJAX request to tbl_zoom_select.php for getting the complete row info
- var post_params = {
+ var id = this.id;
+ var fid = 4;
+ currentData = id;
+ // Make AJAX request to tbl_zoom_select.php for getting the complete row info
+ var post_params = {
'ajax_request' : true,
'get_data_row' : true,
'db' : window.parent.db,
'table' : window.parent.table,
'where_clause' : data[id]['where_clause'],
- 'token' : window.parent.token
+ 'token' : window.parent.token,
}
$.post('tbl_zoom_select.php', post_params, function(data) {
- // Row is contained in data.row_info, now fill the displayResultForm with row values
- for ( key in data.row_info) {
- if (data.row_info[key] == null)
- $('#fields_null_id_' + fid).attr('checked', true);
- else
- $('#fieldID_' + fid).val(data.row_info[key]);
- fid++;
- }
- selectedRow = new Object();
- selectedRow = data.row_info;
+ // Row is contained in data.row_info, now fill the displayResultForm with row values
+ for ( key in data.row_info) {
+ if (data.row_info[key] == null)
+ $('#fields_null_id_' + fid).attr('checked', true);
+ else
+ $('#fieldID_' + fid).val(data.row_info[key]);
+ fid++;
+ }
+ selectedRow = new Object();
+ selectedRow = data.row_info;
});
- $("#dataDisplay").dialog("open");
- }
+ $("#dataDisplay").dialog("open");
+ },
}
+ }
+ }
+ },
+ tooltip: {
+ formatter: function() {
+ return this.point.name;
+ }
+ },
+ title: { text: 'Query Results' },
+ xAxis: {
+ title: { text: $('#tableid_0').val() },
+ events: {
+ setExtremes: function(e){
+ this.resetZoom.show();
}
}
- },
- tooltip: {
- formatter: function() {
- return this.point.name;
- }
- },
- title: { text: 'Query Results' },
- xAxis: {
- title: { text: $('#tableid_0').val() }
+
},
yAxis: {
- min: null,
- title: { text: $('#tableid_1').val() }
- }
+ min: null,
+ title: { text: $('#tableid_1').val() },
+ endOnTick: false,
+ startOnTick: false,
+ events: {
+ setExtremes: function(e){
+ this.resetZoom.show();
+ }
+ }
+ },
}
$('#resizer').resizable({
@@ -461,145 +524,185 @@ $(document).ready(function() {
);
}
});
+
+ // Classify types as either numeric,time,text
+ xType = getType(xType);
+ yType = getType(yType);
- // Classify types as either numeric,time,text
- xType = getType(xType);
- yType = getType(yType);
-
- //Set the axis type based on the field
- currentSettings.xAxis.type = (xType == 'time') ? 'datetime' : 'linear';
- currentSettings.yAxis.type = (yType == 'time') ? 'datetime' : 'linear';
+ //Set the axis type based on the field
+ currentSettings.xAxis.type = (xType == 'time') ? 'datetime' : 'linear';
+ currentSettings.yAxis.type = (yType == 'time') ? 'datetime' : 'linear';
// Formulate series data for plot
series[0] = new Object();
series[0].data = new Array();
- series[0].marker = {
+ series[0].marker = {
symbol: 'circle'
};
- if (xType != 'text' && yType != 'text') {
- $.each(data,function(key,value) {
- var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val());
- var yVal = (yType == 'numeric') ? value[yLabel] : getTimeStamp(value[yLabel],$('#types_1').val());
+ if (xType != 'text' && yType != 'text') {
+ $.each(data,function(key,value) {
+ var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val());
+ var yVal = (yType == 'numeric') ? value[yLabel] : getTimeStamp(value[yLabel],$('#types_1').val());
series[0].data.push({ name: value[dataLabel], x: xVal, y: yVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
- xCord.push(value[xLabel]);
- yCord.push(value[yLabel]);
- it++;
+ xCord.push(value[xLabel]);
+ yCord.push(value[yLabel]);
+ it++;
});
- if (xType == 'numeric') {
- currentSettings.xAxis.max = Array.max(xCord) + 6
- currentSettings.xAxis.min = Array.min(xCord) - 6
+ if(xType == 'numeric') {
+ currentSettings.xAxis.max = Array.max(xCord) + 6
+ currentSettings.xAxis.min = Array.min(xCord) - 6
+ }
+ else {
+ currentSettings.xAxis.labels = { formatter : function() {
+ return getDate(this.value, $('#types_0').val());
+ }}
}
- else {
- currentSettings.xAxis.labels = { formatter : function() {
- return getDate(this.value, $('#types_0').val());
- }}
- }
- if (yType == 'numeric') {
- currentSettings.yAxis.max = Array.max(yCord) + 6
- currentSettings.yAxis.min = Array.min(yCord) - 6
- }
- else {
- currentSettings.yAxis.labels = { formatter : function() {
- return getDate(this.value, $('#types_1').val());
- }}
+ if(yType == 'numeric') {
+ currentSettings.yAxis.max = Array.max(yCord) + 6
+ currentSettings.yAxis.min = Array.min(yCord) - 6
+ }
+ else {
+ currentSettings.yAxis.labels = { formatter : function() {
+ return getDate(this.value, $('#types_1').val());
+ }}
}
}
-
- else if (xType =='text' && yType !='text') {
- $.each(data,function(key,value) {
- xCord.push(value[xLabel]);
- yCord.push(value[yLabel]);
- });
-
- tempX = getCord(xCord);
- $.each(data,function(key,value) {
- var yVal = (yType == 'numeric') ? value[yLabel] : getTimeStamp(value[yLabel],$('#types_1').val());
+
+ else if (xType =='text' && yType !='text') {
+ $.each(data,function(key,value) {
+ xCord.push(value[xLabel]);
+ yCord.push(value[yLabel]);
+ });
+
+ tempX = getCord(xCord);
+ $.each(data,function(key,value) {
+ var yVal = (yType == 'numeric') ? value[yLabel] : getTimeStamp(value[yLabel],$('#types_1').val());
series[0].data.push({ name: value[dataLabel], x: tempX[0][it], y: yVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
- it++;
+ it++;
});
-
- currentSettings.xAxis.labels = { formatter : function() {
- if (tempX[1][this.value] && tempX[1][this.value].length > 10)
- return tempX[1][this.value].substring(0,10)
- else
- return tempX[1][this.value];
- }
+
+ currentSettings.xAxis.labels = { formatter : function() {
+ if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+ return tempX[1][this.value].substring(0,10)
+ else
+ return tempX[1][this.value];
+ }
}
- if (yType == 'numeric') {
- currentSettings.yAxis.max = Array.max(yCord) + 6
- currentSettings.yAxis.min = Array.min(yCord) - 6
+ if(yType == 'numeric') {
+ currentSettings.yAxis.max = Array.max(yCord) + 6
+ currentSettings.yAxis.min = Array.min(yCord) - 6
+ }
+ else {
+ currentSettings.yAxis.labels = { formatter : function() {
+ return getDate(this.value, $('#types_1').val());
+ }}
}
- else {
- currentSettings.yAxis.labels = { formatter : function() {
- return getDate(this.value, $('#types_1').val());
- }}
- }
- xCord = tempX[2];
- }
-
- else if (xType !='text' && yType =='text') {
- $.each(data,function(key,value) {
- xCord.push(value[xLabel]);
- yCord.push(value[yLabel]);
- });
- tempY = getCord(yCord);
- $.each(data,function(key,value) {
- var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val());
+ xCord = tempX[2];
+ }
+
+ else if (xType !='text' && yType =='text') {
+ $.each(data,function(key,value) {
+ xCord.push(value[xLabel]);
+ yCord.push(value[yLabel]);
+ });
+ tempY = getCord(yCord);
+ $.each(data,function(key,value) {
+ var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val());
series[0].data.push({ name: value[dataLabel], y: tempY[0][it], x: xVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
- it++;
+ it++;
});
- if (xType == 'numeric') {
- currentSettings.xAxis.max = Array.max(xCord) + 6
- currentSettings.xAxis.min = Array.min(xCord) - 6
+ if(xType == 'numeric') {
+ currentSettings.xAxis.max = Array.max(xCord) + 6
+ currentSettings.xAxis.min = Array.min(xCord) - 6
+ }
+ else {
+ currentSettings.xAxis.labels = { formatter : function() {
+ return getDate(this.value, $('#types_0').val());
+ }}
}
- else {
- currentSettings.xAxis.labels = { formatter : function() {
- return getDate(this.value, $('#types_0').val());
- }}
+ currentSettings.yAxis.labels = { formatter : function() {
+ if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+ return tempY[1][this.value].substring(0,10)
+ else
+ return tempY[1][this.value];
+ }
}
- currentSettings.yAxis.labels = { formatter : function() {
- if (tempY[1][this.value] && tempY[1][this.value].length > 10)
- return tempY[1][this.value].substring(0,10)
- else
- return tempY[1][this.value];
- }
- }
- yCord = tempY[2];
- }
-
- else if (xType =='text' && yType =='text') {
- $.each(data,function(key,value) {
- xCord.push(value[xLabel]);
- yCord.push(value[yLabel]);
- });
- tempX = getCord(xCord);
- tempY = getCord(yCord);
- $.each(data,function(key,value) {
+ yCord = tempY[2];
+ }
+
+ else if (xType =='text' && yType =='text') {
+ $.each(data,function(key,value) {
+ xCord.push(value[xLabel]);
+ yCord.push(value[yLabel]);
+ });
+ tempX = getCord(xCord);
+ tempY = getCord(yCord);
+ $.each(data,function(key,value) {
series[0].data.push({ name: value[dataLabel], x: tempX[0][it], y: tempY[0][it], marker: {fillColor: colorCodes[it % 8]} , id: it } );
- it++;
+ it++;
});
- currentSettings.xAxis.labels = { formatter : function() {
- if (tempX[1][this.value] && tempX[1][this.value].length > 10) {
- return tempX[1][this.value].substring(0,10)
- } else {
- return tempX[1][this.value];
- }
- }};
- currentSettings.yAxis.labels = { formatter : function() {
- if (tempY[1][this.value] && tempY[1][this.value].length > 10) {
- return tempY[1][this.value].substring(0,10);
- } else {
- return tempY[1][this.value];
- }
- }};
- xCord = tempX[2];
- yCord = tempY[2];
+ currentSettings.xAxis.labels = { formatter : function() {
+ if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+ return tempX[1][this.value].substring(0,10)
+ else
+ return tempX[1][this.value];
+ }
+ }
+ currentSettings.yAxis.labels = { formatter : function() {
+ if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+ return tempY[1][this.value].substring(0,10)
+ else
+ return tempY[1][this.value];
+ }
+ }
+ xCord = tempX[2];
+ yCord = tempY[2];
- }
+ }
- currentSettings.series = series;
+ currentSettings.series = series;
currentChart = PMA_createChart(currentSettings);
- scrollToChart();
+ xMin = currentChart.xAxis[0].getExtremes().min;
+ xMax = currentChart.xAxis[0].getExtremes().max;
+ yMin = currentChart.yAxis[0].getExtremes().min;
+ yMax = currentChart.yAxis[0].getExtremes().max;
+ includePan(currentChart); //Enable panning feature
+ var setZoom = function() {
+ var newxm = xMin + (xMax - xMin) * (1 - zoomRatio) / 2;
+ var newxM = xMax - (xMax - xMin) * (1 - zoomRatio) / 2;
+ var newym = yMin + (yMax - yMin) * (1 - zoomRatio) / 2;
+ var newyM = yMax - (yMax - yMin) * (1 - zoomRatio) / 2;
+ currentChart.xAxis[0].setExtremes(newxm,newxM);
+ currentChart.yAxis[0].setExtremes(newym,newyM);
+ };
+ //Enable zoom feature
+ $("#querychart").mousewheel(function(objEvent, intDelta) {
+ if (intDelta > 0) {
+ if (zoomRatio > 0.1) {
+ zoomRatio = zoomRatio - 0.1;
+ setZoom();
+ }
+ }
+ else if (intDelta < 0) {
+ zoomRatio = zoomRatio + 0.1;
+ setZoom();
+ }
+ });
+ //Add reset zoom feature
+ currentChart.yAxis[0].resetZoom = currentChart.xAxis[0].resetZoom = $('Reset zoom')
+ .appendTo(currentChart.container)
+ .css({
+ position: 'absolute',
+ top: 10,
+ right: 20,
+ display: 'none'
+ })
+ .click(function(){
+ currentChart.xAxis[0].setExtremes(null, null)
+ currentChart.yAxis[0].setExtremes(null, null)
+ this.style.display = 'none'
+ });
+ scrollToChart();
}
});
diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php
index 3942e0003e..518121d95a 100644
--- a/tbl_zoom_select.php
+++ b/tbl_zoom_select.php
@@ -21,6 +21,7 @@ $GLOBALS['js_include'][] = 'sql.js';
$GLOBALS['js_include'][] = 'functions.js';
$GLOBALS['js_include'][] = 'tbl_zoom_plot.js';
$GLOBALS['js_include'][] = 'date.js';
+$GLOBALS['js_include'][] = 'jquery/jquery.mousewheel.js';
$GLOBALS['js_include'][] = 'highcharts/highcharts.js';
/* Files required for chart exporting */
$GLOBALS['js_include'][] = 'highcharts/exporting.js';