From ed98d7ead90a73e64602ee20621d54f0b33f39dc Mon Sep 17 00:00:00 2001
From: Ammar Yasir
Date: Mon, 15 Aug 2011 17:18:07 +0530
Subject: [PATCH 1/5] Added: Mousewheel zoom and panning feature
---
js/{ => jquery}/date.js | 0
js/tbl_zoom_plot.js | 86 ++++++++++++++++++++++++++++++++++++++---
tbl_zoom_select.php | 4 +-
3 files changed, 83 insertions(+), 7 deletions(-)
rename js/{ => jquery}/date.js (100%)
diff --git a/js/date.js b/js/jquery/date.js
similarity index 100%
rename from js/date.js
rename to js/jquery/date.js
diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js
index b9c0d75364..92f3775d4c 100644
--- a/js/tbl_zoom_plot.js
+++ b/js/tbl_zoom_plot.js
@@ -63,7 +63,7 @@ function getDate(val,type) {
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)
+ return Highcharts.dateFormat('%H:%M:%S', val)
}
else if (type.toString().search(/date/i) != -1) {
return Highcharts.dateFormat('%Y-%m-%e', val)
@@ -121,6 +121,50 @@ function scrollToChart() {
$('html,body').animate({scrollTop: x}, 500);
}
+/**
+ ** Handlers for panning feature
+ **/
+function includePan(currentChart) {
+ var mouseDown;
+ var lastX;
+ var lastY;
+ $('#querychart').mousedown(function() {
+ mouseDown = 1;
+ });
+
+ $('#querychart').mouseup(function() {
+ mouseDown = 0;
+ });
+
+ $('#querychart').mousemove(function(e) {
+ if (mouseDown == 1) {
+ if (e.pageX > lastX) {
+ var diff = e.pageX - lastX;
+ var xExtremes = currentChart.xAxis[0].getExtremes();
+ currentChart.xAxis[0].setExtremes(xExtremes.min - diff, xExtremes.max - diff);
+ }
+ else if (e.pageX < lastX) {
+ var diff = lastX - e.pageX;
+ var xExtremes = currentChart.xAxis[0].getExtremes();
+ currentChart.xAxis[0].setExtremes(xExtremes.min + diff, xExtremes.max + diff);
+ }
+
+ if (e.pageY > lastY) {
+ var ydiff = 1 * (e.pageY - lastY);
+ var yExtremes = currentChart.yAxis[0].getExtremes();
+ currentChart.yAxis[0].setExtremes(yExtremes.min + ydiff, yExtremes.max + ydiff);
+ }
+ else if (e.pageY < lastY) {
+ var ydiff = 1 * (lastY - e.pageY);
+ var yExtremes = currentChart.yAxis[0].getExtremes();
+ currentChart.yAxis[0].setExtremes(yExtremes.min - ydiff, yExtremes.max - ydiff);
+ }
+ }
+ lastX = e.pageX;
+ lastY = e.pageY;
+ });
+}
+
$(document).ready(function() {
/**
@@ -139,6 +183,10 @@ $(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
var data = jQuery.parseJSON($('#querydata').html());
@@ -371,22 +419,23 @@ $(document).ready(function() {
.text(PMA_messages['strShowSearchCriteria'])
$('#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 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',
+ //zoomType: 'xy',
width:$('#resizer').width() -3,
height:$('#resizer').height()-20
},
@@ -600,6 +649,33 @@ $(document).ready(function() {
currentSettings.series = series;
currentChart = PMA_createChart(currentSettings);
+ 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);
+ 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);
+ };
+ $("#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();
+ }
+ });
scrollToChart();
+
}
});
diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php
index cdb784d00b..9dd86f9e2a 100644
--- a/tbl_zoom_select.php
+++ b/tbl_zoom_select.php
@@ -20,12 +20,12 @@ $GLOBALS['js_include'][] = 'makegrid.js';
$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/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';
$GLOBALS['js_include'][] = 'canvg/canvg.js';
-$GLOBALS['js_include'][] = 'canvg/rgbcolor.js';
$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
$GLOBALS['js_include'][] = 'jquery/timepicker.js';
From 7a821c8a367c78116b3cfc649ca1c4c8e10cd861 Mon Sep 17 00:00:00 2001
From: Ammar Yasir
Date: Fri, 19 Aug 2011 09:03:55 +0530
Subject: [PATCH 2/5] Improved the panning feature
---
js/{jquery => }/date.js | 0
js/tbl_zoom_plot.js | 662 +++++++++++++++++++---------------------
tbl_zoom_select.php | 2 +-
3 files changed, 318 insertions(+), 346 deletions(-)
rename js/{jquery => }/date.js (100%)
diff --git a/js/jquery/date.js b/js/date.js
similarity index 100%
rename from js/jquery/date.js
rename to js/date.js
diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js
index 026d305934..cb40e11584 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,24 +59,15 @@ function isEmpty(obj) {
** @param type String Field type(datetime/timestamp/time/date)
**/
function getDate(val,type) {
-<<<<<<< HEAD
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)
}
-=======
- 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)
- }
->>>>>>> phpmyadmin/master
else if (type.toString().search(/date/i) != -1) {
return Highcharts.dateFormat('%Y-%m-%e', val)
- }
+ }
}
/**
@@ -85,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
**/
@@ -137,6 +128,8 @@ function includePan(currentChart) {
var mouseDown;
var lastX;
var lastY;
+ var chartWidth = $('#resizer').width() - 3;
+ var chartHeight = $('#resizer').height() - 20;
$('#querychart').mousedown(function() {
mouseDown = 1;
});
@@ -144,28 +137,27 @@ function includePan(currentChart) {
$('#querychart').mouseup(function() {
mouseDown = 0;
});
-
$('#querychart').mousemove(function(e) {
if (mouseDown == 1) {
if (e.pageX > lastX) {
- var diff = e.pageX - lastX;
- var xExtremes = currentChart.xAxis[0].getExtremes();
+ 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 diff = lastX - e.pageX;
- var xExtremes = currentChart.xAxis[0].getExtremes();
+ 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 ydiff = 1 * (e.pageY - lastY);
- var yExtremes = currentChart.yAxis[0].getExtremes();
+ 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 ydiff = 1 * (lastY - e.pageY);
- var yExtremes = currentChart.yAxis[0].getExtremes();
+ 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);
}
}
@@ -184,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();
@@ -197,7 +189,7 @@ $(document).ready(function() {
var zoomRatio = 1;
- // Get query result
+ // Get query result
var data = jQuery.parseJSON($('#querydata').html());
/**
@@ -221,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
**/
$('')
@@ -248,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')
@@ -426,9 +418,8 @@ $(document).ready(function() {
.hide();
$('#togglesearchformlink')
.text(PMA_messages['strShowSearchCriteria'])
- $('#togglesearchformdiv').show();
+ $('#togglesearchformdiv').show();
var selectedRow;
-<<<<<<< HEAD
var colorCodes = ['#FF0000','#00FFFF','#0000FF','#0000A0','#FF0080','#800080','#FFFF00','#00FF00','#FF00FF'];
var series = new Array();
var xCord = new Array();
@@ -439,22 +430,10 @@ $(document).ready(function() {
var xMin; // xAxis extreme min
var yMax; // yAxis extreme max
var yMin; // yAxis extreme min
-=======
- 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;
->>>>>>> phpmyadmin/master
// Set the basic plot settings
var currentSettings = {
chart: {
-<<<<<<< HEAD
renderTo: 'querychart',
type: 'scatter',
//zoomType: 'xy',
@@ -463,74 +442,66 @@ $(document).ready(function() {
},
credits: {
enabled: false
-=======
- renderTo: 'querychart',
- type: 'scatter',
- zoomType: 'xy',
- width:$('#resizer').width() -3,
- height:$('#resizer').height()-20
->>>>>>> phpmyadmin/master
},
- 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;
- }
- },
+ }
+ }
+ },
+ tooltip: {
+ formatter: function() {
+ return this.point.name;
+ }
+ },
title: { text: 'Query Results' },
- xAxis: {
- title: { text: $('#tableid_0').val() }
+ 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
+ },
}
$('#resizer').resizable({
@@ -542,150 +513,150 @@ $(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);
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);
+ includePan(currentChart); //Enable panning feature
var setZoom = function() {
var newxm = xMin + (xMax - xMin) * (1 - zoomRatio) / 2;
var newxM = xMax - (xMax - xMin) * (1 - zoomRatio) / 2;
@@ -694,11 +665,11 @@ $(document).ready(function() {
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();
}
}
@@ -708,5 +679,6 @@ $(document).ready(function() {
}
});
scrollToChart();
+
}
});
diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php
index 12a09142fa..518121d95a 100644
--- a/tbl_zoom_select.php
+++ b/tbl_zoom_select.php
@@ -20,7 +20,7 @@ $GLOBALS['js_include'][] = 'makegrid.js';
$GLOBALS['js_include'][] = 'sql.js';
$GLOBALS['js_include'][] = 'functions.js';
$GLOBALS['js_include'][] = 'tbl_zoom_plot.js';
-$GLOBALS['js_include'][] = 'jquery/date.js';
+$GLOBALS['js_include'][] = 'date.js';
$GLOBALS['js_include'][] = 'jquery/jquery.mousewheel.js';
$GLOBALS['js_include'][] = 'highcharts/highcharts.js';
/* Files required for chart exporting */
From 01d5a76ca992bb521530a804ef358c3ec3e5094c Mon Sep 17 00:00:00 2001
From: Ammar Yasir
Date: Fri, 19 Aug 2011 09:13:01 +0530
Subject: [PATCH 3/5] Added "Reset Zoom" link that reverts the plot to original
display.
---
js/tbl_zoom_plot.js | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js
index cb40e11584..e773175d7a 100644
--- a/js/tbl_zoom_plot.js
+++ b/js/tbl_zoom_plot.js
@@ -495,12 +495,23 @@ $(document).ready(function() {
title: { text: 'Query Results' },
xAxis: {
title: { text: $('#tableid_0').val() },
+ events: {
+ setExtremes: function(e){
+ this.resetZoom.show();
+ }
+ }
+
},
yAxis: {
min: null,
title: { text: $('#tableid_1').val() },
endOnTick: false,
- startOnTick: false
+ startOnTick: false,
+ events: {
+ setExtremes: function(e){
+ this.resetZoom.show();
+ }
+ }
},
}
@@ -678,7 +689,20 @@ $(document).ready(function() {
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();
-
}
});
From b441555d688ce1d01b71a0f241b29257d4765298 Mon Sep 17 00:00:00 2001
From: Ammar Yasir
Date: Sat, 20 Aug 2011 10:58:33 +0530
Subject: [PATCH 4/5] Added FAQ in Documentation.html about 'How to use Zoom
search feature?' (FAQ 6.32)
---
Documentation.html | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
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
From cae2c2a52b54c0dbdf952283cfd29baf2d9d03cf Mon Sep 17 00:00:00 2001
From: Ammar Yasir
Date: Sat, 20 Aug 2011 11:02:47 +0530
Subject: [PATCH 5/5] Modified the 'How to use?' message for info about
mousewheel zoom and panning feature
---
js/messages.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
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.')
. '
- '