From 699ca1d3904b0324a8d1fe0359ac40a725e6e92f Mon Sep 17 00:00:00 2001 From: root Date: Wed, 18 May 2011 22:30:26 +0530 Subject: [PATCH 01/46] Just testing upload --- upload_test | 1 + 1 file changed, 1 insertion(+) create mode 100644 upload_test diff --git a/upload_test b/upload_test new file mode 100644 index 0000000000..ec2ecb962a --- /dev/null +++ b/upload_test @@ -0,0 +1 @@ +This is testing push commands From aac58fd425e4ee4064fa5dbbe666304c5e2b6f2c Mon Sep 17 00:00:00 2001 From: root Date: Wed, 18 May 2011 22:40:33 +0530 Subject: [PATCH 02/46] testing for push --- config.sample.inc.php | 2 +- db_structure.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config.sample.inc.php b/config.sample.inc.php index 0ea16d5f76..2cf344dcaf 100644 --- a/config.sample.inc.php +++ b/config.sample.inc.php @@ -14,7 +14,7 @@ * This is needed for cookie based authentication to encrypt password in * cookie */ -$cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */ +$cfg['blowfish_secret'] = 'a8b7c6d'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */ /* * Servers configuration diff --git a/db_structure.php b/db_structure.php index d81af5d536..b594fcb9f2 100644 --- a/db_structure.php +++ b/db_structure.php @@ -55,6 +55,8 @@ require_once './libraries/db_structure.lib.php'; $titles = PMA_buildActionTitles(); // 1. No tables +echo "Testing"; + if ($num_tables == 0) { echo '

' . __('No tables found in database') . '

' . "\n"; From ae44636606a9c7b98d9f5d4998486579a4610a83 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Mon, 23 May 2011 21:26:07 +0530 Subject: [PATCH 03/46] Made some changes on the tbl_select.php page to add a link for Zoom Search. Please dont mind the coding, I just coded very quickly to get back comments. If the flow of the interface is ok I'll code it properly. --- db_structure.php | 1 - js/messages.php | 2 + js/tbl_select.js | 39 ++++++++++++++- tbl_select.php | 122 +++++++++++++++++++++++++++++++++++++++++++++-- upload_test | 1 - 5 files changed, 159 insertions(+), 6 deletions(-) delete mode 100644 upload_test diff --git a/db_structure.php b/db_structure.php index b594fcb9f2..6f318f195e 100644 --- a/db_structure.php +++ b/db_structure.php @@ -55,7 +55,6 @@ require_once './libraries/db_structure.lib.php'; $titles = PMA_buildActionTitles(); // 1. No tables -echo "Testing"; if ($num_tables == 0) { echo '

' . __('No tables found in database') . '

' . "\n"; diff --git a/js/messages.php b/js/messages.php index 0f7c8c7c67..0b4f373931 100644 --- a/js/messages.php +++ b/js/messages.php @@ -92,6 +92,8 @@ $js_messages['strHide'] = __('Hide'); /* For tbl_select.js */ $js_messages['strHideSearchCriteria'] = __('Hide search criteria'); $js_messages['strShowSearchCriteria'] = __('Show search criteria'); +$js_messages['strTableSearch'] = __('Table Search'); +$js_messages['strZoomSearch'] = __('Zoom Search'); /* For tbl_change.js */ $js_messages['strIgnore'] = __('Ignore'); diff --git a/js/tbl_select.js b/js/tbl_select.js index 8115245cbc..e220daaa82 100644 --- a/js/tbl_select.js +++ b/js/tbl_select.js @@ -21,8 +21,45 @@ $(document).ready(function() { $.ajaxSetup({ cache: 'false' }); + + /** + * Makes the operator and value field hidden initially, then toggles between visibile and hidden on userclick + */ + /* $('a').each(function(index) { + if($(this).text() == "Table Search"){ + alert(index + ': ' + $(this).text()); + alert($('#subtabid').val()); + } + });*/ - /** + $('#zoom_search_form').hide(); + if($('#id_flag').val()==2) + { + $('#tbl_search_form').hide(); + $('#zoom_search_form').show(); + + } + + $('#tbl_search_id').click(function() { + $('#zoom_search_form').hide(); + $('#tbl_search_form').show(); + }); + + $('#zoom_search_id').click(function() { + $('#tbl_search_form').hide(); + $('#zoom_search_form').show(); + }); + + $('#tableID1').change(function() { + $('#zoom_search_form').submit(); + }) + + $('#tableID2').change(function() { + $('#zoom_search_form').submit(); + }) + + + /** * Prepare a div containing a link, otherwise it's incorrectly displayed * after a couple of clicks */ diff --git a/tbl_select.php b/tbl_select.php index 2cb0086293..02243842c9 100644 --- a/tbl_select.php +++ b/tbl_select.php @@ -36,6 +36,7 @@ if ($GLOBALS['cfg']['PropertiesIconic'] == true) { /** * Not selection yet required -> displays the selection form */ + if (!isset($param) || $param[0] == '') { // Gets some core libraries require_once './libraries/tbl_common.php'; @@ -97,17 +98,46 @@ if (!isset($param) || $param[0] == '') { // check also foreigners even if relwork is FALSE (to get // foreign keys from innodb) $foreigners = PMA_getForeigners($db, $table); + $flag = 1; ?> + +
+ +
> + + + do the work diff --git a/upload_test b/upload_test deleted file mode 100644 index ec2ecb962a..0000000000 --- a/upload_test +++ /dev/null @@ -1 +0,0 @@ -This is testing push commands From 7396fa3aa9544c480b11edc1b3b2d687b1bca5e8 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Thu, 26 May 2011 12:22:16 +0530 Subject: [PATCH 04/46] Designed the zoom-search form(tbl_zoom_select.php) -> User selecte exactly two columns. -> Generates two queries, one for each column criteria. --- js/tbl_select.js | 47 ++--- tbl_select.php | 110 ++---------- tbl_zoom_select.php | 418 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 443 insertions(+), 132 deletions(-) create mode 100644 tbl_zoom_select.php diff --git a/js/tbl_select.js b/js/tbl_select.js index e220daaa82..387aa518e3 100644 --- a/js/tbl_select.js +++ b/js/tbl_select.js @@ -21,45 +21,22 @@ $(document).ready(function() { $.ajaxSetup({ cache: 'false' }); - - /** - * Makes the operator and value field hidden initially, then toggles between visibile and hidden on userclick - */ - /* $('a').each(function(index) { - if($(this).text() == "Table Search"){ - alert(index + ': ' + $(this).text()); - alert($('#subtabid').val()); - } - });*/ - $('#zoom_search_form').hide(); - if($('#id_flag').val()==2) - { - $('#tbl_search_form').hide(); - $('#zoom_search_form').show(); - - } - - $('#tbl_search_id').click(function() { - $('#zoom_search_form').hide(); - $('#tbl_search_form').show(); - }); - - $('#zoom_search_id').click(function() { - $('#tbl_search_form').hide(); - $('#zoom_search_form').show(); - }); + /* + * Handle events from zoom-search page + * + */ - $('#tableID1').change(function() { - $('#zoom_search_form').submit(); - }) - - $('#tableID2').change(function() { - $('#zoom_search_form').submit(); + $('#tableid_1').change(function() { + $('#zoom_search_form').submit(); }) - - /** + $('#tableid_2').change(function() { + $('#zoom_search_form').submit(); + }) + + + /** * Prepare a div containing a link, otherwise it's incorrectly displayed * after a couple of clicks */ diff --git a/tbl_select.php b/tbl_select.php index 02243842c9..8732c1c592 100644 --- a/tbl_select.php +++ b/tbl_select.php @@ -36,8 +36,7 @@ if ($GLOBALS['cfg']['PropertiesIconic'] == true) { /** * Not selection yet required -> displays the selection form */ - -if (!isset($param) || $param[0] == '') { +if (! isset($param) || $param[0] == '') { // Gets some core libraries require_once './libraries/tbl_common.php'; //$err_url = 'tbl_select.php' . $err_url; @@ -53,7 +52,7 @@ if (!isset($param) || $param[0] == '') { */ require_once './libraries/tbl_links.inc.php'; - if (!isset($goto)) { + if (! isset($goto)) { $goto = $GLOBALS['cfg']['DefaultTabTable']; } // Defines the url to return to in case of error in the next sql statement @@ -111,33 +110,29 @@ $subtabs = array(); $subtabs['search']['icon'] = 'b_search.png'; $subtabs['search']['text'] = __('Table Search'); -$subtabs['search']['link'] = ''; +$subtabs['search']['link'] = 'tbl_select.php'; $subtabs['search']['id'] = 'tbl_search_id'; $subtabs['search']['args']['pos'] = 0; $subtabs['zoom']['icon'] = 'b_props.png'; -$subtabs['zoom']['link'] = ''; +$subtabs['zoom']['link'] = 'tbl_zoom_select.php'; $subtabs['zoom']['text'] = __('Zoom Search'); $subtabs['zoom']['id'] = 'zoom_search_id'; echo PMA_generate_html_tabs($subtabs, $url_params); unset($subtabs); - -if($trial[0]=='' || $trail[0]!==''){ - ?>
> - - + do the work */ @@ -452,7 +368,7 @@ else { } elseif (strncasecmp($types[$i], 'enum', 4) == 0) { if (!empty($fields[$i])) { - if (!is_array($fields[$i])) { + if (! is_array($fields[$i])) { $fields[$i] = explode(',', $fields[$i]); } $enum_selected_count = count($fields[$i]); diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php new file mode 100644 index 0000000000..efc8879fb4 --- /dev/null +++ b/tbl_zoom_select.php @@ -0,0 +1,418 @@ +'; + + if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { + $titles['Browse'] .= __('Browse foreign values'); + } +} else { + $titles['Browse'] = __('Browse foreign values'); +} +/** + * Not selection yet required -> displays the selection form + */ +if (! isset($zoom_submit)) { + // Gets some core libraries + require_once './libraries/tbl_common.php'; + //$err_url = 'tbl_select.php' . $err_url; + $url_query .= '&goto=tbl_select.php&back=tbl_select.php'; + + /** + * Gets tables informations + */ + require_once './libraries/tbl_info.inc.php'; + + /** + * Displays top menu links + */ + require_once './libraries/tbl_links.inc.php'; + + if (! isset($goto)) { + $goto = $GLOBALS['cfg']['DefaultTabTable']; + } + // Defines the url to return to in case of error in the next sql statement + $err_url = $goto . '?' . PMA_generate_common_url($db, $table); + + // Gets the list and number of fields + $result = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE); + $fields_cnt = PMA_DBI_num_rows($result); + $fields_list = $fields_null = $fields_type = $fields_collation = array(); + while ($row = PMA_DBI_fetch_assoc($result)) { + $fields_list[] = $row['Field']; + $type = $row['Type']; + // reformat mysql query output + if (strncasecmp($type, 'set', 3) == 0 + || strncasecmp($type, 'enum', 4) == 0) { + $type = str_replace(',', ', ', $type); + } else { + + // strip the "BINARY" attribute, except if we find "BINARY(" because + // this would be a BINARY or VARBINARY field type + if (!preg_match('@BINARY[\(]@i', $type)) { + $type = preg_replace('@BINARY@i', '', $type); + } + $type = preg_replace('@ZEROFILL@i', '', $type); + $type = preg_replace('@UNSIGNED@i', '', $type); + + $type = strtolower($type); + } + if (empty($type)) { + $type = ' '; + } + $fields_null[] = $row['Null']; + $fields_type[] = $type; + $fields_collation[] = !empty($row['Collation']) && $row['Collation'] != 'NULL' + ? $row['Collation'] + : ''; + } // end while + PMA_DBI_free_result($result); + unset($result, $type); + + // retrieve keys into foreign fields, if any + // check also foreigners even if relwork is FALSE (to get + // foreign keys from innodb) + $foreigners = PMA_getForeigners($db, $table); + $flag = 1; + $tbl_fields_type =array(); + $tbl_fields_collation =array(); + $tbl_fields_null =array(); + ?> + +
+ + + + +
> + + + + /> + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + ' . "\n"; + // go back to first row + + // here, the 4th parameter is empty because there is no current + // value of data for the dropdown (the search page initial values + // are displayed empty) + echo PMA_foreignDropdown($foreignData['disp_row'], + $foreignData['foreign_field'], + $foreignData['foreign_display'], + '', $GLOBALS['cfg']['ForeignKeyMaxLimit']); + echo ' ' . "\n"; + } elseif ($foreignData['foreign_link'] == true) { + ?> + + + ' . "\n"; + for ($j = 0; $j < $cnt_enum_value; $j++) { + if(isset($fields[$i-1]) && is_array($fields[$i-1]) && in_array($enum_value[$j],$fields[$i-1])){ + echo ' '; + } + else{ + echo ' '; + } + } // end for + echo ' ' . "\n"; + } else { + // o t h e r c a s e s + $the_class = 'textfield'; + $type = $tbl_fields_type[$i-1]; + if ($type == 'date') { + $the_class .= ' datefield'; + } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') { + $the_class .= ' datetimefield'; + } + if(isset($fields[$i-1]) && is_string($fields[$i-1])){ + echo ' ' . "\n"; + } + else{ + echo ' ' . "\n"; + } + }; + } + ?> + + +
+
+
+ + +
+
+ +
+ + +
+ + 1) { + $func_type = $func[$i] = 'IN'; + $parens_open = '('; + $parens_close = ')'; + + } elseif ($func_type == '!=' && $enum_selected_count > 1) { + $func_type = $func[$i] = 'NOT IN'; + $parens_open = '('; + $parens_close = ')'; + } else { + $parens_open = ''; + $parens_close = ''; + } + $enum_where = '\'' . PMA_sqlAddslashes($fields[$i][0]) . '\''; + for ($e = 1; $e < $enum_selected_count; $e++) { + $enum_where .= ', \'' . PMA_sqlAddslashes($fields[$i][$e]) . '\''; + } + + $w[] = PMA_backquote($inputs[$i]) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close; + } + + } elseif ($fields[$i] != '') { + // For these types we quote the value. Even if it's another type (like INT), + // for a LIKE we always quote the value. MySQL converts strings to numbers + // and numbers to strings as necessary during the comparison + if (preg_match('@char|binary|blob|text|set|date|time|year@i', $types[$i]) || strpos(' ' . $func_type, 'LIKE')) { + $quot = '\''; + } else { + $quot = ''; + } + + // LIKE %...% + if ($func_type == 'LIKE %...%') { + $func_type = 'LIKE'; + $fields[$i] = '%' . $fields[$i] . '%'; + } + if ($func_type == 'REGEXP ^...$') { + $func_type = 'REGEXP'; + $fields[$i] = '^' . $fields[$i] . '$'; + } + + if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') { + $func_type = str_replace(' (...)', '', $func_type); + + // quote values one by one + $values = explode(',', $fields[$i]); + foreach ($values as &$value) + $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot; + + if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') + $w[] = PMA_backquote($inputs[$i]) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); + else + $w[] = PMA_backquote($inputs[$i]) . ' ' . $func_type . ' (' . implode(',', $values) . ')'; + } + else { + $w[] = PMA_backquote($inputs[$i]) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields[$i]) . $quot;; + } + + } // end if + + if ($w) { + $sql_query .= ' WHERE ' . implode(' AND ', $w); + } + echo $sql_query."
"; + } +} + +?> From 91d372f9bcca4b92e6e63d7354fcf2a81b6b8f18 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Sun, 29 May 2011 12:16:13 +0530 Subject: [PATCH 05/46] Added a library file for the table-search and zoom-search code Contains two functions: -> Get Field list and details -> Get where clause of query generation process --- libraries/tbl_select.lib.php | 151 +++++++++++++++++++++++++++++++++++ tbl_select.php | 135 ++++--------------------------- tbl_zoom_select.php | 135 ++++--------------------------- 3 files changed, 181 insertions(+), 240 deletions(-) create mode 100644 libraries/tbl_select.lib.php diff --git a/libraries/tbl_select.lib.php b/libraries/tbl_select.lib.php new file mode 100644 index 0000000000..59bdd6da11 --- /dev/null +++ b/libraries/tbl_select.lib.php @@ -0,0 +1,151 @@ + 1) { + $func_type = 'IN'; + $parens_open = '('; + $parens_close = ')'; + + } elseif ($func_type == '!=' && $enum_selected_count > 1) { + $func_type = 'NOT IN'; + $parens_open = '('; + $parens_close = ')'; + + } else { + $parens_open = ''; + $parens_close = ''; + } + $enum_where = '\'' . PMA_sqlAddslashes($fields[0]) . '\''; + for ($e = 1; $e < $enum_selected_count; $e++) { + $enum_where .= ', \'' . PMA_sqlAddslashes($fields[$e]) . '\''; + } + + $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close; + } + + } elseif ($fields != '') { + // For these types we quote the value. Even if it's another type (like INT), + // for a LIKE we always quote the value. MySQL converts strings to numbers + // and numbers to strings as necessary during the comparison + if (preg_match('@char|binary|blob|text|set|date|time|year@i', $types) || strpos(' ' . $func_type, 'LIKE')) { + $quot = '\''; + } else { + $quot = ''; + } + + // LIKE %...% + if ($func_type == 'LIKE %...%') { + $func_type = 'LIKE'; + $fields = '%' . $fields . '%'; + } + if ($func_type == 'REGEXP ^...$') { + $func_type = 'REGEXP'; + $fields = '^' . $fields . '$'; + } + + if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') { + $func_type = str_replace(' (...)', '', $func_type); + + // quote values one by one + $values = explode(',', $fields); + foreach ($values as &$value) + $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot; + + if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') + $w = PMA_backquote($names) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); + else + $w = PMA_backquote($names) . ' ' . $func_type . ' (' . implode(',', $values) . ')'; + } + else { + $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields) . $quot;; + } + + } // end if + + return $w; +} + +function PMA_tbl_getSubTabs(){ + + $subtabs = array(); + + $subtabs['search']['icon'] = 'b_search.png'; + $subtabs['search']['text'] = __('Table Search'); + $subtabs['search']['link'] = 'tbl_select.php'; + $subtabs['search']['id'] = 'tbl_search_id'; + $subtabs['search']['args']['pos'] = 0; + + $subtabs['zoom']['icon'] = 'b_props.png'; + $subtabs['zoom']['link'] = 'tbl_zoom_select.php'; + $subtabs['zoom']['text'] = __('Zoom Search'); + $subtabs['zoom']['id'] = 'zoom_search_id'; + + return $subtabs; + +} + +?> diff --git a/tbl_select.php b/tbl_select.php index 8732c1c592..a2fd6194f3 100644 --- a/tbl_select.php +++ b/tbl_select.php @@ -15,6 +15,7 @@ */ require_once './libraries/common.inc.php'; require_once './libraries/mysql_charsets.lib.php'; +require_once './libraries/tbl_select.lib.php'; $GLOBALS['js_include'][] = 'sql.js'; $GLOBALS['js_include'][] = 'tbl_select.js'; @@ -59,39 +60,13 @@ if (! isset($param) || $param[0] == '') { $err_url = $goto . '?' . PMA_generate_common_url($db, $table); // Gets the list and number of fields - $result = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE); - $fields_cnt = PMA_DBI_num_rows($result); - $fields_list = $fields_null = $fields_type = $fields_collation = array(); - while ($row = PMA_DBI_fetch_assoc($result)) { - $fields_list[] = $row['Field']; - $type = $row['Type']; - // reformat mysql query output - if (strncasecmp($type, 'set', 3) == 0 - || strncasecmp($type, 'enum', 4) == 0) { - $type = str_replace(',', ', ', $type); - } else { - // strip the "BINARY" attribute, except if we find "BINARY(" because - // this would be a BINARY or VARBINARY field type - if (!preg_match('@BINARY[\(]@i', $type)) { - $type = preg_replace('@BINARY@i', '', $type); - } - $type = preg_replace('@ZEROFILL@i', '', $type); - $type = preg_replace('@UNSIGNED@i', '', $type); - - $type = strtolower($type); - } - if (empty($type)) { - $type = ' '; - } - $fields_null[] = $row['Null']; - $fields_type[] = $type; - $fields_collation[] = !empty($row['Collation']) && $row['Collation'] != 'NULL' - ? $row['Collation'] - : ''; - } // end while - PMA_DBI_free_result($result); - unset($result, $type); + $fields_array = PMA_tbl_getFields($table,$db); + $fields_list = $fields_array[0]; + $fields_type = $fields_array[1]; + $fields_collation = $fields_array[2]; + $fields_null = $fields_array[3]; + $fields_cnt = count($fields_list); // retrieve keys into foreign fields, if any // check also foreigners even if relwork is FALSE (to get @@ -106,21 +81,8 @@ $url_params = array(); $url_params['db'] = $db; $url_params['table'] = $table; -$subtabs = array(); +echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params); -$subtabs['search']['icon'] = 'b_search.png'; -$subtabs['search']['text'] = __('Table Search'); -$subtabs['search']['link'] = 'tbl_select.php'; -$subtabs['search']['id'] = 'tbl_search_id'; -$subtabs['search']['args']['pos'] = 0; - -$subtabs['zoom']['icon'] = 'b_props.png'; -$subtabs['zoom']['link'] = 'tbl_zoom_select.php'; -$subtabs['zoom']['text'] = __('Zoom Search'); -$subtabs['zoom']['id'] = 'zoom_search_id'; - -echo PMA_generate_html_tabs($subtabs, $url_params); -unset($subtabs); ?>
> @@ -361,79 +323,15 @@ else { $cnt_func = count($func); reset($func); while (list($i, $func_type) = each($func)) { - list($charsets[$i]) = explode('_', $collations[$i]); - if (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) { - $fields[$i] = ''; - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type; - - } elseif (strncasecmp($types[$i], 'enum', 4) == 0) { - if (!empty($fields[$i])) { - if (! is_array($fields[$i])) { - $fields[$i] = explode(',', $fields[$i]); - } - $enum_selected_count = count($fields[$i]); - if ($func_type == '=' && $enum_selected_count > 1) { - $func_type = $func[$i] = 'IN'; - $parens_open = '('; - $parens_close = ')'; - - } elseif ($func_type == '!=' && $enum_selected_count > 1) { - $func_type = $func[$i] = 'NOT IN'; - $parens_open = '('; - $parens_close = ')'; - - } else { - $parens_open = ''; - $parens_close = ''; - } - $enum_where = '\'' . PMA_sqlAddslashes($fields[$i][0]) . '\''; - for ($e = 1; $e < $enum_selected_count; $e++) { - $enum_where .= ', \'' . PMA_sqlAddslashes($fields[$i][$e]) . '\''; - } - - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close; - } - - } elseif ($fields[$i] != '') { - // For these types we quote the value. Even if it's another type (like INT), - // for a LIKE we always quote the value. MySQL converts strings to numbers - // and numbers to strings as necessary during the comparison - if (preg_match('@char|binary|blob|text|set|date|time|year@i', $types[$i]) || strpos(' ' . $func_type, 'LIKE')) { - $quot = '\''; - } else { - $quot = ''; - } - - // LIKE %...% - if ($func_type == 'LIKE %...%') { - $func_type = 'LIKE'; - $fields[$i] = '%' . $fields[$i] . '%'; - } - if ($func_type == 'REGEXP ^...$') { - $func_type = 'REGEXP'; - $fields[$i] = '^' . $fields[$i] . '$'; - } - - if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') { - $func_type = str_replace(' (...)', '', $func_type); - - // quote values one by one - $values = explode(',', $fields[$i]); - foreach ($values as &$value) - $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot; - - if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); - else - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' (' . implode(',', $values) . ')'; - } - else { - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields[$i]) . $quot;; - } - - } // end if + + list($charsets[$i]) = explode('_', $collations[$i]); + $unaryFlag = (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false; + $whereClause = PMA_tbl_search_getWhereClause($fields[$i],$names[$i], $types[$i], $collations[$i], $func_type, $unaryFlag); + if($whereClause) + $w[] = $whereClause; + } // end for - + //print_r($w); if ($w) { $sql_query .= ' WHERE ' . implode(' AND ', $w); } @@ -442,7 +340,6 @@ else { if ($orderField != '--nil--') { $sql_query .= ' ORDER BY ' . PMA_backquote($orderField) . ' ' . $order; } // end if - require './sql.php'; } diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index efc8879fb4..5e59bdd8d3 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -12,6 +12,7 @@ */ require_once './libraries/common.inc.php'; require_once './libraries/mysql_charsets.lib.php'; +require_once './libraries/tbl_select.lib.php'; $GLOBALS['js_include'][] = 'sql.js'; $GLOBALS['js_include'][] = 'tbl_select.js'; @@ -55,39 +56,14 @@ if (! isset($zoom_submit)) { $err_url = $goto . '?' . PMA_generate_common_url($db, $table); // Gets the list and number of fields - $result = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE); - $fields_cnt = PMA_DBI_num_rows($result); - $fields_list = $fields_null = $fields_type = $fields_collation = array(); - while ($row = PMA_DBI_fetch_assoc($result)) { - $fields_list[] = $row['Field']; - $type = $row['Type']; - // reformat mysql query output - if (strncasecmp($type, 'set', 3) == 0 - || strncasecmp($type, 'enum', 4) == 0) { - $type = str_replace(',', ', ', $type); - } else { - // strip the "BINARY" attribute, except if we find "BINARY(" because - // this would be a BINARY or VARBINARY field type - if (!preg_match('@BINARY[\(]@i', $type)) { - $type = preg_replace('@BINARY@i', '', $type); - } - $type = preg_replace('@ZEROFILL@i', '', $type); - $type = preg_replace('@UNSIGNED@i', '', $type); + $fields_array = PMA_tbl_getFields($table,$db); + $fields_list = $fields_array[0]; + $fields_type = $fields_array[1]; + $fields_collation = $fields_array[2]; + $fields_null = $fields_array[3]; + $fields_cnt = count($fields_list); - $type = strtolower($type); - } - if (empty($type)) { - $type = ' '; - } - $fields_null[] = $row['Null']; - $fields_type[] = $type; - $fields_collation[] = !empty($row['Collation']) && $row['Collation'] != 'NULL' - ? $row['Collation'] - : ''; - } // end while - PMA_DBI_free_result($result); - unset($result, $type); // retrieve keys into foreign fields, if any // check also foreigners even if relwork is FALSE (to get @@ -105,21 +81,7 @@ $url_params = array(); $url_params['db'] = $db; $url_params['table'] = $table; -$subtabs = array(); - -$subtabs['search']['icon'] = 'b_search.png'; -$subtabs['search']['text'] = __('Table Search'); -$subtabs['search']['link'] = 'tbl_select.php'; -$subtabs['search']['id'] = 'tbl_search_id'; -$subtabs['search']['args']['pos'] = 0; - -$subtabs['zoom']['icon'] = 'b_props.png'; -$subtabs['zoom']['link'] = 'tbl_zoom_select.php'; -$subtabs['zoom']['text'] = __('Zoom Search'); -$subtabs['zoom']['id'] = 'zoom_search_id'; - -echo PMA_generate_html_tabs($subtabs, $url_params); -unset($subtabs); +echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params); ?> 1) { - $func_type = $func[$i] = 'IN'; - $parens_open = '('; - $parens_close = ')'; - - } elseif ($func_type == '!=' && $enum_selected_count > 1) { - $func_type = $func[$i] = 'NOT IN'; - $parens_open = '('; - $parens_close = ')'; - } else { - $parens_open = ''; - $parens_close = ''; - } - $enum_where = '\'' . PMA_sqlAddslashes($fields[$i][0]) . '\''; - for ($e = 1; $e < $enum_selected_count; $e++) { - $enum_where .= ', \'' . PMA_sqlAddslashes($fields[$i][$e]) . '\''; - } - - $w[] = PMA_backquote($inputs[$i]) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close; - } - - } elseif ($fields[$i] != '') { - // For these types we quote the value. Even if it's another type (like INT), - // for a LIKE we always quote the value. MySQL converts strings to numbers - // and numbers to strings as necessary during the comparison - if (preg_match('@char|binary|blob|text|set|date|time|year@i', $types[$i]) || strpos(' ' . $func_type, 'LIKE')) { - $quot = '\''; - } else { - $quot = ''; - } - - // LIKE %...% - if ($func_type == 'LIKE %...%') { - $func_type = 'LIKE'; - $fields[$i] = '%' . $fields[$i] . '%'; - } - if ($func_type == 'REGEXP ^...$') { - $func_type = 'REGEXP'; - $fields[$i] = '^' . $fields[$i] . '$'; - } - - if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') { - $func_type = str_replace(' (...)', '', $func_type); - - // quote values one by one - $values = explode(',', $fields[$i]); - foreach ($values as &$value) - $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot; - - if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') - $w[] = PMA_backquote($inputs[$i]) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); - else - $w[] = PMA_backquote($inputs[$i]) . ' ' . $func_type . ' (' . implode(',', $values) . ')'; - } - else { - $w[] = PMA_backquote($inputs[$i]) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields[$i]) . $quot;; - } - - } // end if - - if ($w) { - $sql_query .= ' WHERE ' . implode(' AND ', $w); + $unaryFlag = (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false; + $w = PMA_tbl_search_getWhereClause($fields[$i],$inputs[$i], $types[$i], $collations[$i], $func_type, $unaryFlag); + if ($w != '') { + $sql_query .= ' WHERE ' . $w; } - echo $sql_query."
"; + print $sql_query."
"; } } From c7cef3b0ba0de9af03bcd9d733290e69882d5a29 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Tue, 31 May 2011 19:02:50 +0530 Subject: [PATCH 06/46] Refactored the tbl_select.php and tbl_zoom_select.php code in libraries/tbl_select.lib.php Parts refactored are: -> Setting titles -> getting fields list -> setting sub-tabs -> setting table header of QBE display -> displaying foreign data -> search criteria input elements --- js/tbl_select.js | 14 +- libraries/tbl_select.lib.php | 240 ++++++++++++++++++++++++++++++++--- tbl_select.php | 74 +---------- tbl_zoom_select.php | 114 ++++------------- 4 files changed, 254 insertions(+), 188 deletions(-) diff --git a/js/tbl_select.js b/js/tbl_select.js index 387aa518e3..a66920d1a3 100644 --- a/js/tbl_select.js +++ b/js/tbl_select.js @@ -22,16 +22,18 @@ $(document).ready(function() { cache: 'false' }); - /* - * Handle events from zoom-search page - * - */ + /*if($('#id_flag').val()==2) + { + $('#tbl_search_form').hide(); + $('#zoom_search_form').show(); - $('#tableid_1').change(function() { + }*/ + + $('#tableid_0').change(function() { $('#zoom_search_form').submit(); }) - $('#tableid_2').change(function() { + $('#tableid_1').change(function() { $('#zoom_search_form').submit(); }) diff --git a/libraries/tbl_select.lib.php b/libraries/tbl_select.lib.php index 59bdd6da11..6f301429bc 100644 --- a/libraries/tbl_select.lib.php +++ b/libraries/tbl_select.lib.php @@ -9,6 +9,54 @@ * @package phpMyAdmin */ +require_once 'url_generating.lib.php'; + + + + /** + * PMA_tbl_setTitle() sets the title for foreign keys display link + * + * @param $propertiesIconic Type of icon property + * @param $themeImage Icon Image + * @return string $str Value of the Title + * + */ + +function PMA_tbl_setTitle($propertiesIconic,$pmaThemeImage){ + if ($propertiesIconic == true) { + $str = '' . __('Browse foreign values') . ''; + + if ($propertiesIconic === 'both') { + $str .= __('Browse foreign values'); + return $str; + } + } else { + return __('Browse foreign values'); + } +} + + /** + * PMA_tbl_getFields() gets all the fields of a table along with their types,collations and whether null or not. + * + * @uses PMA_DBI_query() + * @uses PMA_backquote() + * @uses PMA_DBI_num_rows() + * @uses PMA_DBI_fetch_assoc() + * @uses PMA_DBI_free_result() + * @uses preg_replace() + * @uses str_replace() + * @uses strncasecmp() + * @uses empty() + * + * @param $db Selected database + * @param $table Selected table + * + * @return array($fields_list,$fields_type,$fields_collation,$fields_null) Array containing the field list, field types, collations and null constatint + * + */ + function PMA_tbl_getFields($table,$db) { // Gets the list and number of fields @@ -51,10 +99,179 @@ function PMA_tbl_getFields($table,$db) { } +/* PMA_tbl_setTableHeader() sets the table header for displaying a table in query-by-example format + * + * @return HTML content, the tags and content for table header + * + */ + +function PMA_tbl_setTableHeader(){ + +return ' + ' . __('Column') . ' + ' . __('Type') . ' + ' . __('Collation') . ' + ' . __('Operator') . ' + ' . __('Value') . ' + + '; + + +} + +/* PMA_tbl_getSubTabs() returns an array with necessary configrations to create sub-tabs(Table Search and Zoom Search) in the table_select page + * + * @return array $subtabs Array containing configuration (icon,text,link,id,args) of sub-tabs for Table Search and Zoom search + * + */ + +function PMA_tbl_getSubTabs(){ + + $subtabs = array(); + + $subtabs['search']['icon'] = 'b_search.png'; + $subtabs['search']['text'] = __('Table Search'); + $subtabs['search']['link'] = 'tbl_select.php'; + $subtabs['search']['id'] = 'tbl_search_id'; + $subtabs['search']['args']['pos'] = 0; + + $subtabs['zoom']['icon'] = 'b_props.png'; + $subtabs['zoom']['link'] = 'tbl_zoom_select.php'; + $subtabs['zoom']['text'] = __('Zoom Search'); + $subtabs['zoom']['id'] = 'zoom_search_id'; + + return $subtabs; + +} + + +/* PMA_tbl_getForeignFields_Values() creates the HTML content for: 1) Browsing foreign data for a field. 2) Creating elements for search criteria input on fields. + * + * @uses PMA_foreignDropdown + * @uses PMA_generate_common_url + * @uses isset() + * @uses is_array() + * @uses in_array() + * @uses urlencode() + * @uses str_replace() + * @uses stbstr() + * + * @param $foreigners Array of foreign keys + * @param $foreignData Foreign keys data + * @param $field Column name + * @param $tbl_fields_type Column type + * @param $i Column index + * @param $db Selected database + * @param $table Selected table + * @param $titles Selected title + * @param $foreignMaxLimit Max limit of displaying foreign elements + * @param $fields Array of search criteria inputs + * + * @return string $str HTML content for viewing foreing data and elements for search criteria input. + * + */ + +function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i, $db, $table,$titles,$foreignMaxLimit, $fields){ + + $str = ''; + + if ($foreigners && isset($foreigners[$field]) && is_array($foreignData['disp_row'])) { + + // f o r e i g n k e y s + $str .= ' ' . "\n"; + } elseif ($foreignData['foreign_link'] == true) { + + $str .= '' ; ?> + + '; + // ' . str_replace("'", "\'", $titles['Browse']) . '\');'; + // ]] + $str .= ''; + ?> + ' . "\n"; + for ($j = 0; $j < $cnt_enum_value; $j++) { + if(isset($fields[$i]) && is_array($fields[$i]) && in_array($enum_value[$j],$fields[$i])){ + $str .= ' '; + } + else{ + $str .= ' '; + } + } // end for + $str .= ' ' . "\n"; + } else { + // o t h e r c a s e s + $the_class = 'textfield'; + $type = $tbl_fields_type[$i]; + if ($type == 'date') { + $the_class .= ' datefield'; + } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') { + $the_class .= ' datetimefield'; + } + if(isset($fields[$i]) && is_string($fields[$i])){ + $str .= ' ' . "\n"; + } + else{ + $str .= ' ' . "\n"; + } + }; + return $str; + +} + + +/* PMA_tbl_search_getWhereClause() Return the where clause for query generation based on the inputs provided. + * + * @uses PMA_backquote + * @uses PMA_sqlAddslashes + * @uses preg_match + * @uses isset() + * @uses in_array() + * @uses str_replace() + * @uses strpos() + * @uses explode() + * @uses trim() + * + * @param $fields Search criteria input + * @param $names Name of the field(column) on which search criteria is submitted + * @param $types Type of the field + * @param $collations Field collation + * @param $func_type Search fucntion/operator + * @param $unaryFlag Whether operator unary or not + * + * @return string $str HTML content for viewing foreing data and elements for search criteria input. + * + */ + function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $func_type, $unaryFlag){ - //Return the where clause for query generation based on the inputs provided in the tbl_select.php form - + + $w = ''; if($unaryFlag){ $fields = ''; $w = PMA_backquote($names) . ' ' . $func_type; @@ -128,24 +345,5 @@ function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $fu return $w; } - -function PMA_tbl_getSubTabs(){ - - $subtabs = array(); - - $subtabs['search']['icon'] = 'b_search.png'; - $subtabs['search']['text'] = __('Table Search'); - $subtabs['search']['link'] = 'tbl_select.php'; - $subtabs['search']['id'] = 'tbl_search_id'; - $subtabs['search']['args']['pos'] = 0; - - $subtabs['zoom']['icon'] = 'b_props.png'; - $subtabs['zoom']['link'] = 'tbl_zoom_select.php'; - $subtabs['zoom']['text'] = __('Zoom Search'); - $subtabs['zoom']['id'] = 'zoom_search_id'; - - return $subtabs; - -} ?> diff --git a/tbl_select.php b/tbl_select.php index a2fd6194f3..ee89c13c64 100644 --- a/tbl_select.php +++ b/tbl_select.php @@ -21,18 +21,8 @@ $GLOBALS['js_include'][] = 'sql.js'; $GLOBALS['js_include'][] = 'tbl_select.js'; $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js'; $GLOBALS['js_include'][] = 'jquery/timepicker.js'; -if ($GLOBALS['cfg']['PropertiesIconic'] == true) { - $titles['Browse'] = - '' . __('Browse foreign values') . ''; - if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { - $titles['Browse'] .= __('Browse foreign values'); - } -} else { - $titles['Browse'] = __('Browse foreign values'); -} +$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage); /** * Not selection yet required -> displays the selection form @@ -72,7 +62,6 @@ if (! isset($param) || $param[0] == '') { // check also foreigners even if relwork is FALSE (to get // foreign keys from innodb) $foreigners = PMA_getForeigners($db, $table); - $flag = 1; ?>
@@ -95,14 +84,7 @@ echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
- - - - - - - - + ' . "\n"; - // go back to first row - - // here, the 4th parameter is empty because there is no current - // value of data for the dropdown (the search page initial values - // are displayed empty) - echo PMA_foreignDropdown($foreignData['disp_row'], - $foreignData['foreign_field'], - $foreignData['foreign_display'], - '', $GLOBALS['cfg']['ForeignKeyMaxLimit']); - echo ' ' . "\n"; - } elseif ($foreignData['foreign_link'] == true) { - ?> - - - ' . "\n"; - for ($j = 0; $j < $cnt_enum_value; $j++) { - echo ' '; - } // end for - echo ' ' . "\n"; - } else { - // o t h e r c a s e s - $the_class = 'textfield'; - $type = $fields_type[$i]; - if ($type == 'date') { - $the_class .= ' datefield'; - } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') { - $the_class .= ' datetimefield'; - } - echo ' ' . "\n"; - }; - ?> + echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $fields_type, $i, $db, $table, $titles,$GLOBALS['cfg']['ForeignKeyMaxLimit'], '' ); + + ?> '; - if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { - $titles['Browse'] .= __('Browse foreign values'); - } -} else { - $titles['Browse'] = __('Browse foreign values'); -} +$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage); + /** * Not selection yet required -> displays the selection form */ @@ -114,26 +105,19 @@ if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null
- - - - - - - - - + + - - + + From 70167fed52368079d1cbffd445514480f29d9ff3 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Wed, 1 Jun 2011 01:22:31 +0530 Subject: [PATCH 07/46] Made suggested change to tbl_select.php and tbl_zoom_select.php --- js/tbl_select.js | 10 +- libraries/tbl_select.lib.php | 272 +++++++++++++++++------------------ tbl_select.php | 6 +- tbl_zoom_select.php | 180 ++++++++++++----------- 4 files changed, 228 insertions(+), 240 deletions(-) diff --git a/js/tbl_select.js b/js/tbl_select.js index a66920d1a3..1442bbe46b 100644 --- a/js/tbl_select.js +++ b/js/tbl_select.js @@ -22,13 +22,9 @@ $(document).ready(function() { cache: 'false' }); - /*if($('#id_flag').val()==2) - { - $('#tbl_search_form').hide(); - $('#zoom_search_form').show(); - - }*/ - + /** + * Form submit on field change + */ $('#tableid_0').change(function() { $('#zoom_search_form').submit(); }) diff --git a/libraries/tbl_select.lib.php b/libraries/tbl_select.lib.php index 6f301429bc..a78404b421 100644 --- a/libraries/tbl_select.lib.php +++ b/libraries/tbl_select.lib.php @@ -11,8 +11,6 @@ require_once 'url_generating.lib.php'; - - /** * PMA_tbl_setTitle() sets the title for foreign keys display link * @@ -23,14 +21,14 @@ require_once 'url_generating.lib.php'; */ function PMA_tbl_setTitle($propertiesIconic,$pmaThemeImage){ - if ($propertiesIconic == true) { - $str = '' . __('Browse foreign values') . ''; + if ($propertiesIconic == true) { + $str = '' . __('Browse foreign values') . ''; - if ($propertiesIconic === 'both') { - $str .= __('Browse foreign values'); - return $str; + if ($propertiesIconic === 'both') { + $str .= __('Browse foreign values'); + return $str; } } else { return __('Browse foreign values'); @@ -108,7 +106,7 @@ function PMA_tbl_getFields($table,$db) { function PMA_tbl_setTableHeader(){ return ' - + @@ -127,20 +125,20 @@ return ' function PMA_tbl_getSubTabs(){ - $subtabs = array(); + $subtabs = array(); - $subtabs['search']['icon'] = 'b_search.png'; - $subtabs['search']['text'] = __('Table Search'); - $subtabs['search']['link'] = 'tbl_select.php'; - $subtabs['search']['id'] = 'tbl_search_id'; - $subtabs['search']['args']['pos'] = 0; + $subtabs['search']['icon'] = 'b_search.png'; + $subtabs['search']['text'] = __('Table Search'); + $subtabs['search']['link'] = 'tbl_select.php'; + $subtabs['search']['id'] = 'tbl_search_id'; + $subtabs['search']['args']['pos'] = 0; - $subtabs['zoom']['icon'] = 'b_props.png'; - $subtabs['zoom']['link'] = 'tbl_zoom_select.php'; - $subtabs['zoom']['text'] = __('Zoom Search'); - $subtabs['zoom']['id'] = 'zoom_search_id'; + $subtabs['zoom']['icon'] = 'b_props.png'; + $subtabs['zoom']['link'] = 'tbl_zoom_select.php'; + $subtabs['zoom']['text'] = __('Zoom Search'); + $subtabs['zoom']['id'] = 'zoom_search_id'; - return $subtabs; + return $subtabs; } @@ -173,47 +171,46 @@ function PMA_tbl_getSubTabs(){ function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i, $db, $table,$titles,$foreignMaxLimit, $fields){ - $str = ''; + $str = ''; - if ($foreigners && isset($foreigners[$field]) && is_array($foreignData['disp_row'])) { + if ($foreigners && isset($foreigners[$field]) && is_array($foreignData['disp_row'])) { - // f o r e i g n k e y s - $str .= ' ' . "\n"; + // go back to first row + // here, the 4th parameter is empty because there is no current + // value of data for the dropdown (the search page initial values + // are displayed empty) + $str .= PMA_foreignDropdown($foreignData['disp_row'], + $foreignData['foreign_field'], + $foreignData['foreign_display'], + '', $foreignMaxLimit); + $str .= ' ' . "\n"; + } + elseif ($foreignData['foreign_link'] == true) { - // here, the 4th parameter is empty because there is no current - // value of data for the dropdown (the search page initial values - // are displayed empty) - $str .= PMA_foreignDropdown($foreignData['disp_row'], - $foreignData['foreign_field'], - $foreignData['foreign_display'], - '', $foreignMaxLimit); - $str .= ' ' . "\n"; - } elseif ($foreignData['foreign_link'] == true) { - - $str .= '' ; ?> + $str .= '' ; ?> - '; - // '; + // ' . str_replace("'", "\'", $titles['Browse']) . '\');'; - // ]] - $str .= ''; - ?> - ' . "\n"; + $str .= '' . PMA_generate_common_url($db, $table) . '&field=' . urlencode($field) . '&fieldkey=' . $i . '">' . str_replace("'", "\'", $titles['Browse']) . '\');'; + // ]] + $str .= ''; + } + elseif (strncasecmp($tbl_fields_type[$i], 'enum', 4) == 0) { + // e n u m s + $enum_value=explode(', ', str_replace("'", '', substr($tbl_fields_type[$i], 5, -1))); + $cnt_enum_value = count($enum_value); + $str .= '' . "\n"; - } else { - // o t h e r c a s e s - $the_class = 'textfield'; - $type = $tbl_fields_type[$i]; - if ($type == 'date') { - $the_class .= ' datefield'; - } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') { - $the_class .= ' datetimefield'; - } - if(isset($fields[$i]) && is_string($fields[$i])){ - $str .= ' ' . "\n"; - } - else{ - $str .= ' ' . "\n"; - } - }; - return $str; + $str .= ' ' . "\n"; + } + else { + // o t h e r c a s e s + $the_class = 'textfield'; + $type = $tbl_fields_type[$i]; + if ($type == 'date') { + $the_class .= ' datefield'; + } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') { + $the_class .= ' datetimefield'; + } + if(isset($fields[$i]) && is_string($fields[$i])){ + $str .= ' ' . "\n"; + } + else{ + $str .= ' ' . "\n"; + } + }; + return $str; } @@ -271,79 +269,79 @@ EOT; function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $func_type, $unaryFlag){ - $w = ''; - if($unaryFlag){ - $fields = ''; - $w = PMA_backquote($names) . ' ' . $func_type; + $w = ''; + if($unaryFlag){ + $fields = ''; + $w = PMA_backquote($names) . ' ' . $func_type; - } elseif (strncasecmp($types, 'enum', 4) == 0) { - if (!empty($fields)) { - if (! is_array($fields)) { - $fields = explode(',', $fields); - } - $enum_selected_count = count($fields); - if ($func_type == '=' && $enum_selected_count > 1) { - $func_type = 'IN'; - $parens_open = '('; - $parens_close = ')'; + } elseif (strncasecmp($types, 'enum', 4) == 0) { + if (!empty($fields)) { + if (! is_array($fields)) { + $fields = explode(',', $fields); + } + $enum_selected_count = count($fields); + if ($func_type == '=' && $enum_selected_count > 1) { + $func_type = 'IN'; + $parens_open = '('; + $parens_close = ')'; - } elseif ($func_type == '!=' && $enum_selected_count > 1) { - $func_type = 'NOT IN'; - $parens_open = '('; - $parens_close = ')'; + } elseif ($func_type == '!=' && $enum_selected_count > 1) { + $func_type = 'NOT IN'; + $parens_open = '('; + $parens_close = ')'; - } else { - $parens_open = ''; - $parens_close = ''; - } - $enum_where = '\'' . PMA_sqlAddslashes($fields[0]) . '\''; - for ($e = 1; $e < $enum_selected_count; $e++) { - $enum_where .= ', \'' . PMA_sqlAddslashes($fields[$e]) . '\''; - } + } else { + $parens_open = ''; + $parens_close = ''; + } + $enum_where = '\'' . PMA_sqlAddslashes($fields[0]) . '\''; + for ($e = 1; $e < $enum_selected_count; $e++) { + $enum_where .= ', \'' . PMA_sqlAddslashes($fields[$e]) . '\''; + } - $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close; - } + $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close; + } - } elseif ($fields != '') { - // For these types we quote the value. Even if it's another type (like INT), - // for a LIKE we always quote the value. MySQL converts strings to numbers - // and numbers to strings as necessary during the comparison - if (preg_match('@char|binary|blob|text|set|date|time|year@i', $types) || strpos(' ' . $func_type, 'LIKE')) { - $quot = '\''; - } else { - $quot = ''; - } + } elseif ($fields != '') { + // For these types we quote the value. Even if it's another type (like INT), + // for a LIKE we always quote the value. MySQL converts strings to numbers + // and numbers to strings as necessary during the comparison + if (preg_match('@char|binary|blob|text|set|date|time|year@i', $types) || strpos(' ' . $func_type, 'LIKE')) { + $quot = '\''; + } else { + $quot = ''; + } - // LIKE %...% - if ($func_type == 'LIKE %...%') { - $func_type = 'LIKE'; - $fields = '%' . $fields . '%'; - } - if ($func_type == 'REGEXP ^...$') { - $func_type = 'REGEXP'; - $fields = '^' . $fields . '$'; - } + // LIKE %...% + if ($func_type == 'LIKE %...%') { + $func_type = 'LIKE'; + $fields = '%' . $fields . '%'; + } + if ($func_type == 'REGEXP ^...$') { + $func_type = 'REGEXP'; + $fields = '^' . $fields . '$'; + } - if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') { - $func_type = str_replace(' (...)', '', $func_type); + if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') { + $func_type = str_replace(' (...)', '', $func_type); - // quote values one by one - $values = explode(',', $fields); - foreach ($values as &$value) - $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot; + // quote values one by one + $values = explode(',', $fields); + foreach ($values as &$value) + $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot; - if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') - $w = PMA_backquote($names) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); - else - $w = PMA_backquote($names) . ' ' . $func_type . ' (' . implode(',', $values) . ')'; - } - else { - $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields) . $quot;; - } + if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') + $w = PMA_backquote($names) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); + else + $w = PMA_backquote($names) . ' ' . $func_type . ' (' . implode(',', $values) . ')'; + } + else { + $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields) . $quot;; + } - } // end if + } // end if - return $w; + return $w; } ?> diff --git a/tbl_select.php b/tbl_select.php index ee89c13c64..cbd697e32c 100644 --- a/tbl_select.php +++ b/tbl_select.php @@ -51,11 +51,7 @@ if (! isset($param) || $param[0] == '') { // Gets the list and number of fields - $fields_array = PMA_tbl_getFields($table,$db); - $fields_list = $fields_array[0]; - $fields_type = $fields_array[1]; - $fields_collation = $fields_array[2]; - $fields_null = $fields_array[3]; + list($fields_list, $fields_type, $fields_collation, $fields_null) = PMA_tbl_getFields($table,$db); $fields_cnt = count($fields_list); // retrieve keys into foreign fields, if any diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index fb85ab40fa..91b8c3d5b8 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -48,22 +48,15 @@ if (! isset($zoom_submit)) { // Gets the list and number of fields - $fields_array = PMA_tbl_getFields($table,$db); - $fields_list = $fields_array[0]; - $fields_type = $fields_array[1]; - $fields_collation = $fields_array[2]; - $fields_null = $fields_array[3]; + list($fields_list, $fields_type, $fields_collation, $fields_null) = PMA_tbl_getFields($table,$db); $fields_cnt = count($fields_list); - // retrieve keys into foreign fields, if any // check also foreigners even if relwork is FALSE (to get // foreign keys from innodb) $foreigners = PMA_getForeigners($db, $table); $flag = 1; - $tbl_fields_type =array(); - $tbl_fields_collation =array(); - $tbl_fields_null =array(); + $tbl_fields_type = $tbl_fields_collation = $tbl_fields_null = array(); ?>
@@ -79,19 +72,19 @@ echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params); if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null'))) { - $flag = 2; - for($i = 0 ; $i < 2 ; $i++) - { - if($inputs[$i] != __('pma_null')) - { - $key = array_search($inputs[$i],$fields_list); - $tbl_fields_type[$i] = $fields_type[$key]; - $tbl_fields_collation[$i] = $fields_collation[$key]; - $tbl_fields_null[$i] = $fields_null[$key]; - } - + $flag = 2; + for($i = 0 ; $i < 2 ; $i++) + { + if($inputs[$i] != __('pma_null')) + { + $key = array_search($inputs[$i],$fields_list); + $tbl_fields_type[$i] = $fields_type[$key]; + $tbl_fields_collation[$i] = $fields_collation[$key]; + $tbl_fields_null[$i] = $fields_null[$key]; } + } + } ?> @@ -110,21 +103,21 @@ if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null
@@ -132,56 +125,61 @@ if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null + - + + + + + @@ -211,31 +209,31 @@ else { // Unlike tbl_search page this part builds two queries, Query1 for the search criteria on 1st column and Query2 for the other column. This has to be done because user can select two same columns having different criteria. - for($i = 0 ;$i<2;$i++){ + for($i = 0 ; $i < 2 ; $i++){ - $sql_query = 'SELECT '; + $sql_query = 'SELECT '; - // Add the colums to be selected + // Add the colums to be selected - $sql_query .= PMA_backquote($inputs[$i]); + $sql_query .= PMA_backquote($inputs[$i]); - //Add the table + //Add the table - $sql_query .= ' FROM ' . PMA_backquote($table); + $sql_query .= ' FROM ' . PMA_backquote($table); - // The where clause - $charsets = array(); - $cnt_func = count($zoomFunc[$i]); - reset($zoomFunc[$i]); - $func_type = $zoomFunc[$i]; - list($charsets[$i]) = explode('_', $collations[$i]); - $unaryFlag = (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false; - $w = PMA_tbl_search_getWhereClause($fields[$i],$inputs[$i], $types[$i], $collations[$i], $func_type, $unaryFlag); - if ($w != '') { - $sql_query .= ' WHERE ' . $w; - } - print $sql_query."
"; - } + // The where clause + $charsets = array(); + $cnt_func = count($zoomFunc[$i]); + reset($zoomFunc[$i]); + $func_type = $zoomFunc[$i]; + list($charsets[$i]) = explode('_', $collations[$i]); + $unaryFlag = (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false; + $w = PMA_tbl_search_getWhereClause($fields[$i],$inputs[$i], $types[$i], $collations[$i], $func_type, $unaryFlag); + if ($w != '') { + $sql_query .= ' WHERE ' . $w; + } + print $sql_query."
"; + } } ?> From 18694f2d7c81110c35aaa56942cbad5e3d7a4904 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Mon, 6 Jun 2011 04:18:47 +0530 Subject: [PATCH 08/46] Added generate plot feature using SVG ( only for numeric fields ) --- tbl_zoom_select.php | 133 +++++++++++++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 33 deletions(-) diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 91b8c3d5b8..56d23c4a38 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -21,10 +21,11 @@ $GLOBALS['js_include'][] = 'jquery/timepicker.js'; $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage); + /** * Not selection yet required -> displays the selection form */ -if (! isset($zoom_submit)) { +if (true) { // Gets some core libraries require_once './libraries/tbl_common.php'; //$err_url = 'tbl_select.php' . $err_url; @@ -87,8 +88,97 @@ if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null } + +if(isset($zoom_submit)) { + + // Unlike tbl_search page this part builds two queries, Query1 for the search criteria on 1st column and Query2 for the other column. This has to be done because user can select two same columns having different criteria. + $chart =''; + $cx = $cy = $w = array(); + $sql_query = 'SELECT '; + + // Add the colums to be selected + $columns = $inputs; + $columns = PMA_backquote($columns); + $sql_query .= implode(', ', $columns); + + + //Add the table + + $sql_query .= ' FROM ' . PMA_backquote($table); + for($i = 0 ; $i < 2 ; $i++){ + + $tmp = array(); + // The where clause + $charsets = array(); + $cnt_func = count($zoomFunc[$i]); + $func_type = $zoomFunc[$i]; + list($charsets[$i]) = explode('_', $collations[$i]); + $unaryFlag = (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false; + $whereClause = PMA_tbl_search_getWhereClause($fields[$i],$inputs[$i], $types[$i], $collations[$i], $func_type, $unaryFlag); + if($whereClause) + $w[] = $whereClause; + + } // end for + //print_r($w); + if ($w) { + $sql_query .= ' WHERE ' . implode(' AND ', $w); + } + $result = PMA_DBI_query( $sql_query . ";" , null, PMA_DBI_QUERY_STORE); + while ($row = PMA_DBI_fetch_assoc($result)) { + $cx[] = $row[$inputs[0]]; + $cy[] = $row[$inputs[1]]; + } + + for($j = 0 ; $j < count($cx) ; $j++){ + $cx[$j] = 20 + 500 * $cx[$j]/ max($cx); + $cy[$j] = 300 * $cy[$j]/ max($cy) -20 ; + } + $chart .= ' +
+ + + + + + + + + + + + + + + '; + $chart .= $inputs[0]; + $chart .= ' + + + '; + $chart .= $inputs[1]; + $chart .= ' + + + + '; + + for($j = 0 ; $j < count($cx) ; $j++){ + $chart .= ''; + } + + $chart .=' + +
'; + ?> + > @@ -96,10 +186,15 @@ if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null />
+ + +
- + ' . "\n"; - // go back to first row - - // here, the 4th parameter is empty because there is no current - // value of data for the dropdown (the search page initial values - // are displayed empty) - echo PMA_foreignDropdown($foreignData['disp_row'], - $foreignData['foreign_field'], - $foreignData['foreign_display'], - '', $GLOBALS['cfg']['ForeignKeyMaxLimit']); - echo ' ' . "\n"; - } elseif ($foreignData['foreign_link'] == true) { - ?> - - - ' . "\n"; - for ($j = 0; $j < $cnt_enum_value; $j++) { - if(isset($fields[$i-1]) && is_array($fields[$i-1]) && in_array($enum_value[$j],$fields[$i-1])){ - echo ' '; - } - else{ - echo ' '; - } - } // end for - echo ' ' . "\n"; - } else { - // o t h e r c a s e s - $the_class = 'textfield'; - $type = $tbl_fields_type[$i-1]; - if ($type == 'date') { - $the_class .= ' datefield'; - } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') { - $the_class .= ' datetimefield'; - } - if(isset($fields[$i-1]) && is_string($fields[$i-1])){ - echo ' ' . "\n"; - } - else{ - echo ' ' . "\n"; - } - }; - } + if (isset($fields)) + echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i ,$db, $table, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], $fields); + else + echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i ,$db, $table, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], ''); + + } ?> - + + value="" />
' . __('Column') . '
' . __('Column') . ' ' . __('Type') . ' ' . __('Collation') . ' ' . __('Operator') . '
- + + - - - - + else{ ?> + +
- + + +
+ "; - } -} - -?> From f939564bfdfafe0960840b8482fd0a35e249c491 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Thu, 9 Jun 2011 03:03:22 +0530 Subject: [PATCH 09/46] Created the SVG based scatter-plot functionality -> Created classes corresponding to the plot and data objects, currently only data points -> Plots only for numeric fields --- libraries/svg_plot/pma_scatter_plot.php | 238 ++++++++++++++++++++ libraries/svg_plot/pma_svg_data_element.php | 50 ++++ libraries/svg_plot/pma_svg_data_point.php | 86 +++++++ libraries/tbl_select.lib.php | 41 +++- tbl_zoom_select.php | 105 ++++----- 5 files changed, 456 insertions(+), 64 deletions(-) create mode 100644 libraries/svg_plot/pma_scatter_plot.php create mode 100644 libraries/svg_plot/pma_svg_data_element.php create mode 100644 libraries/svg_plot/pma_svg_data_point.php diff --git a/libraries/svg_plot/pma_scatter_plot.php b/libraries/svg_plot/pma_scatter_plot.php new file mode 100644 index 0000000000..cf49a4186f --- /dev/null +++ b/libraries/svg_plot/pma_scatter_plot.php @@ -0,0 +1,238 @@ + array( + '#BCE02E', + '#E0642E', + '#E0D62E', + '#2E97E0', + '#B02EE0', + '#E02E75', + '#5CE02E', + '#E0B02E', + '#000000', + '#0022E0', + '#726CB1', + '#481A36', + '#BAC658', + '#127224', + '#825119', + '#238C74', + '#4C489B', + '#87C9BF', + ), + // Plot background color. + 'bgColor' => '#84AD83', + + // The width of the plot. + 'width' => 520, + + // The height of the plot. + 'height' => 325, + + // Default X Axis label. If empty, label will be taken from the data. + 'xLabel' => '', + + // Default Y Axis label. If empty, label will be taken from the data. + 'yLabel' => '', + + // Data point label. If empty, label will be taken from the data. + 'dataLabel' => '', + + ); + + /** + * @var array Options that the user has specified. + */ + private $_userSpecifiedSettings = null; + + /** + * Returns the settings array + * + * @return the settings array. + */ + public function getSettings() + { + return $this->_settings; + } + + /** + * Returns the data array + * + * @return the data array. + */ + public function getData() + { + return $this->_data; + } + + /** + * Constructor. Stores user specified options. + * + * @param array $data Data for the visualization + * @param array $options Users specified options + */ + public function __construct($data, $options) + { + $this->_userSpecifiedSettings = $options; + $this->_data = $data; + } + + /** + * All the variable initialization, options handling has to be done here. + */ + protected function init() + { + $this->_handleOptions(); + } + + /** + * A function which handles passed parameters. Useful if desired + * chart needs to be a little bit different from the default one. + */ + private function _handleOptions() + { + $this->_dataPoints = array(); + if (! is_null($this->_userSpecifiedSettings)) { + foreach (array_keys($this->_userSpecifiedSettings) as $key){ + $this->_settings[$key] = $this->_userSpecifiedSettings[$key]; + } + } + } + + /** + * Generate the visualization in SVG format. + * + * @return the generated image resource + */ + private function _svg() + { + $this->init(); + + $output = '' . "\n"; + $output .= ''; + $output .= ''; + $output .= ' + + + '; + $output .= ' + '; + $output .= $this->_settings['yLabel']; + $output .= ' + '; + + $output .= ' + '; + $output .= $this->_settings['xLabel']; + $output .= ' + '; + + + $scale_data = $this->_scaleDataSet($this->_data, $this->_settings['xLabel'], $this->_settings['yLabel']); + $output .= $this->_prepareDataSet($this->_data, 0, $scale_data, $this->_settings['dataLabel']); + + $output .= ''; + $output .= ''; + + return $output; + } + + /** + * Get the visualization as a SVG. + * + * @return the visualization as a SVG + */ + public function asSVG() + { + $output = $this->_svg(); + return $output; + } + + /** + * Calculates the scale, horizontal and vertical offset that should be used. + * + * @param array $data Row data + * + * @return an array containing the scale, x and y offsets + */ + private function _scaleDataSet($data,$xField,$yField) + { + // Currently assuming only numeric fields are selected + $cx = $cy = array(); + foreach ($data as $row) { + $cx[] = $row[$xField]; + $cy[] = $row[$yField]; + } + $maxX = max($cx); + $maxY = max($cy); + for($i = 0; $i < count($cx) ; $i++){ + $cx[$i] = 20 + 500 * $cx[$i] / $maxX; + $cy[$i] = 320 * (1 - $cy[$i] / $maxY) + 20; + + } + return array($cx,$cy); + } + + /** + * Prepares and return the dataset as needed by the visualization. + * + * @param array $data Raw data + * @param int $color_number Start index to the color array + * @param array $scale_data Data related to scaling + * @param string $label Label for the data points + * @param image $results Image object in the case of png + * + * @return the formatted array of data. + */ + private function _prepareDataSet($data, $color_number, $scale_data, $label) + { + $result = ''; + // loop through the rows + for($i = 0 ; $i < count($data) ; $i++) { + + $index = $color_number % sizeof($this->_settings['colors']); + + $data_element = new PMA_SVG_Data_Point($scale_data[0][$i],$scale_data[1][$i],$data[$i][$label],$data[$i]); + + $options = array('color' => $this->_settings['colors'][$index], 'id' => $i); + $this->_dataPoints[] = $data_element; + + $result .= $data_element->prepareRowAsSVG($options); + $color_number++; + } + + + return $result; + } +} +?> + diff --git a/libraries/svg_plot/pma_svg_data_element.php b/libraries/svg_plot/pma_svg_data_element.php new file mode 100644 index 0000000000..97f7734572 --- /dev/null +++ b/libraries/svg_plot/pma_svg_data_element.php @@ -0,0 +1,50 @@ +label = $label; + $this->dataRow = $dataRow; + } + + /** + * Handles the generation of each Data Row/Element as a SVG element + * @return the code related to a row in the GIS dataset + */ + public abstract function prepareRowAsSVG($options); + + public function getLabel() + { + return $this->label; + } + + public function setLabel($label) + { + $this->label = $label; + } + + public function getDataRow() + { + return $this->dataRow; + } + + public function setDataRow($dataRow) + { + $this->dataRow = $dataRow; + } +} +?> diff --git a/libraries/svg_plot/pma_svg_data_point.php b/libraries/svg_plot/pma_svg_data_point.php new file mode 100644 index 0000000000..7d01b2b566 --- /dev/null +++ b/libraries/svg_plot/pma_svg_data_point.php @@ -0,0 +1,86 @@ +cx = $cx; + $this->cy = $cy; + + } + + public function prepareRowAsSVG($options) + { + return $this->prepareSvg($options); + } + + /** + * Prepares and returns the code related to a row in the query result as SVG. + * + * @param array $options Array containing options related to properties of the point + * + * @return the code related to a row in the query result. + */ + + protected function prepareSvg($options) + { + $point_options = array( + 'name' => $this->label . '_' .$options['id'], + 'id' => $this->label . 'id' . '_' . $options['id'], + 'class' => 'point', + 'fill' => 'white', + 'stroke' => $options['color'], + 'stroke-width'=> 2, + ); + + $row = ' $val) { + $row .= ' ' . $option . '="' . trim($val) . '"'; + } + $row .= '/>'; + + return $row; + } + + public function getCx() + { + return $this->cx; + } + + public function setCx($cx) + { + $this->cx = $cx; + } + + public function getCy() + { + return $this->cy; + } + + public function setCy($cy) + { + $this->cy = $cy; + } +} +?> diff --git a/libraries/tbl_select.lib.php b/libraries/tbl_select.lib.php index a78404b421..ad3da71d04 100644 --- a/libraries/tbl_select.lib.php +++ b/libraries/tbl_select.lib.php @@ -196,9 +196,9 @@ function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fie '; // ' . str_replace("'", "\'", $titles['Browse']) . '\');'; + $str .= '' . PMA_generate_common_url($db, $table) . '&field=' . urlencode($field) . '&fieldkey=' . $i . '">' . str_replace("'", "\'", $titles['Browse']) . ''; // ]] $str .= ''; } @@ -344,4 +344,41 @@ function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $fu return $w; } +/** + * Formats a SVG plot for the query results. + * + * @param array $data Data for the status chart + * @param array &$settings Settings used to generate the chart + * + * @return string HTML and JS code for the SVG plot + */ +function PMA_SVG_scatter_plot($data, &$settings) +{ + require_once './libraries/svg_plot/pma_scatter_plot.php'; + + if (empty($data)) { + // empty data + return __('No data found for plot.'); + } else { + $scatter_plot = new PMA_Scatter_Plot($data, $settings); + + if ($settings != null) { + foreach ($scatter_plot->getSettings() as $setting => $val) { + if (! isset($settings[$setting])) { + $settings[$setting] = $val; + } + } + } + } + return $scatter_plot->asSVG(); +} + + + + + + + + + ?> diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 56d23c4a38..3f66e51bff 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -91,15 +91,14 @@ if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null if(isset($zoom_submit)) { - // Unlike tbl_search page this part builds two queries, Query1 for the search criteria on 1st column and Query2 for the other column. This has to be done because user can select two same columns having different criteria. - $chart =''; - $cx = $cy = $w = array(); - $sql_query = 'SELECT '; + $w = $data = array(); + + $sql_query = 'SELECT *'; // Add the colums to be selected - $columns = $inputs; - $columns = PMA_backquote($columns); - $sql_query .= implode(', ', $columns); + //$columns = $inputs; + //$columns = PMA_backquote($columns); + //$sql_query .= implode(', ', $columns); //Add the table @@ -123,57 +122,13 @@ if(isset($zoom_submit)) { if ($w) { $sql_query .= ' WHERE ' . implode(' AND ', $w); } + + $settings = array('xLabel' => $inputs[0], 'yLabel' => $inputs[1], 'dataLabel' => $dataLabel); $result = PMA_DBI_query( $sql_query . ";" , null, PMA_DBI_QUERY_STORE); while ($row = PMA_DBI_fetch_assoc($result)) { - $cx[] = $row[$inputs[0]]; - $cy[] = $row[$inputs[1]]; + $data[] = $row; } - - for($j = 0 ; $j < count($cx) ; $j++){ - $cx[$j] = 20 + 500 * $cx[$j]/ max($cx); - $cy[$j] = 300 * $cy[$j]/ max($cy) -20 ; - } - $chart .= ' -
- - - - - - - - - - - - - - - '; - $chart .= $inputs[0]; - $chart .= ' - - - '; - $chart .= $inputs[1]; - $chart .= ' - - - - '; - - for($j = 0 ; $j < count($cx) ; $j++){ - $chart .= ''; - } - - $chart .=' - -
'; - + $scatter_plot = PMA_SVG_scatter_plot($data,$settings); ?> />
- + + +
+ +
- echo $chart; ?> @@ -270,18 +229,40 @@ if(isset($zoom_submit)) {
- - - + + + +
+ + + + +
         +
+ +
Date: Fri, 10 Jun 2011 06:58:23 +0530 Subject: [PATCH 10/46] Fixed some issues and added support for plotting strings --- libraries/svg_plot/pma_scatter_plot.php | 49 +++++++++++++++---- libraries/tbl_select.lib.php | 22 +++++---- tbl_zoom_select.php | 63 ++++++++++++++++++------- 3 files changed, 99 insertions(+), 35 deletions(-) diff --git a/libraries/svg_plot/pma_scatter_plot.php b/libraries/svg_plot/pma_scatter_plot.php index cf49a4186f..10c0aea343 100644 --- a/libraries/svg_plot/pma_scatter_plot.php +++ b/libraries/svg_plot/pma_scatter_plot.php @@ -122,6 +122,10 @@ class PMA_Scatter_Plot $this->_settings[$key] = $this->_userSpecifiedSettings[$key]; } } + if ($this->_settings['dataLabel'] == '') { + $labels = array_keys($this->_data[0]); + $this->_settings['dataLabel'] = $labels[0]; + } } /** @@ -186,20 +190,45 @@ class PMA_Scatter_Plot */ private function _scaleDataSet($data,$xField,$yField) { + // Currently assuming only numeric fields are selected - $cx = $cy = array(); + $coordinates = array(); foreach ($data as $row) { - $cx[] = $row[$xField]; - $cy[] = $row[$yField]; + $coordinates[0][] = $row[$xField]; + $coordinates[1][] = $row[$yField]; } - $maxX = max($cx); - $maxY = max($cy); - for($i = 0; $i < count($cx) ; $i++){ - $cx[$i] = 20 + 500 * $cx[$i] / $maxX; - $cy[$i] = 320 * (1 - $cy[$i] / $maxY) + 20; - + for ($i = 0 ; $i < 2 ; $i++) { + + $maxC = ($i == 0) ? 500 : 320; + + if( !is_numeric($coordinates[$i][0])) { + $uniqueC = array_unique($coordinates[$i]); + $countC = count(array_unique($coordinates[$i])); + $map = $tmp = array(); + foreach ($uniqueC as $uc) { + $tmp[] = $uc; + } + for ($j = 0 ; $j < $countC ; $j++) { + $map[$tmp[$j]] = 20 + $j * $maxC / $countC; + } + for($j = 0 ; $j < count($coordinates[$i]) ; $j++) { + $coordinates[$i][$j] = $map[$coordinates[$i][$j]]; + } + + } + elseif (is_numeric($coordinates[$i][0])) { + + $maxC = max($coordinates[$i]); + for($j = 0 ; $j < count($coordinates[$i]) ; $j++) { + + if ($i == 0) + $coordinates[$i][$j] = 20 + 500 * $coordinates[$i][$j] / $maxC; + else + $coordinates[$i][$j] = 20 + 320 * (1 - $coordinates[$i][$j] / $maxC); + } + } } - return array($cx,$cy); + return $coordinates; } /** diff --git a/libraries/tbl_select.lib.php b/libraries/tbl_select.lib.php index ad3da71d04..71a7de69f1 100644 --- a/libraries/tbl_select.lib.php +++ b/libraries/tbl_select.lib.php @@ -174,7 +174,6 @@ function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fie $str = ''; if ($foreigners && isset($foreigners[$field]) && is_array($foreignData['disp_row'])) { - // f o r e i g n k e y s $str .= ' ' . "\n"; } elseif ($foreignData['foreign_link'] == true) { - - $str .= '' ; ?> - + if(isset($fields[$i]) && is_string($fields[$i])){ + $str .= '' ; + } + else{ + $str .= '' ; + } + ?> '; // asSVG(); } - return $scatter_plot->asSVG(); + } diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 3f66e51bff..1ccad423e8 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -140,15 +140,16 @@ if(isset($zoom_submit)) { /> -
- - +
+ + +
- + @@ -184,29 +185,57 @@ if(isset($zoom_submit)) { if (strncasecmp($tbl_fields_type[$i], 'enum', 4) == 0) { foreach ($GLOBALS['cfg']['EnumOperators'] as $fc) { - echo "\n" . ' ' - . ''; + if(isset($zoomFunc[$i]) && $zoomFunc[$i] == htmlspecialchars($fc)){ + echo "\n" . ' ' + . ''; + } + else { + echo "\n" . ' ' + . ''; + } } } elseif (preg_match('@char|blob|text|set@i', $tbl_fields_type[$i])) { foreach ($GLOBALS['cfg']['TextOperators'] as $fc) { - echo "\n" . ' ' - . ''; + if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){ + echo "\n" . ' ' + . ''; + } + else { + echo "\n" . ' ' + . ''; + } } } else { foreach ($GLOBALS['cfg']['NumOperators'] as $fc) { - echo "\n" . ' ' - . ''; + if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){ + echo "\n" . ' ' + . ''; + } + else { + echo "\n" . ' ' + . ''; + } } } // end if... else... if ($tbl_fields_null[$i]) { foreach ($GLOBALS['cfg']['NullOperators'] as $fc) { - echo "\n" . ' ' - . ''; + if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){ + echo "\n" . ' ' + . ''; + } + else { + echo "\n" . ' ' + . ''; + } } } ?> @@ -217,7 +246,6 @@ if(isset($zoom_submit)) { $field = $inputs[$i]; $foreignData = PMA_getForeignData($foreigners, $field, false, '', ''); - if (isset($fields)) echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i ,$db, $table, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], $fields); else @@ -263,6 +291,7 @@ if(isset($zoom_submit)) {
+
Date: Fri, 17 Jun 2011 01:31:31 +0530 Subject: [PATCH 11/46] Plot functionality using Hihcharts --- js/canvg/canvg.js | 304 +++++++----------------------------- js/highcharts/exporting.js | 13 +- js/highcharts/highcharts.js | 2 +- js/tbl_zoom_plot.js | 129 +++++++++++++++ tbl_zoom_select.php | 18 ++- 5 files changed, 200 insertions(+), 266 deletions(-) create mode 100644 js/tbl_zoom_plot.js diff --git a/js/canvg/canvg.js b/js/canvg/canvg.js index 7b7e963542..83c91b45fc 100644 --- a/js/canvg/canvg.js +++ b/js/canvg/canvg.js @@ -12,6 +12,7 @@ if(!window.console) { window.console.dir = function(str) {}; } +// <3 IE if(!Array.indexOf){ Array.prototype.indexOf = function(obj){ for(var i=0; i ignore mouse events // ignoreAnimation: true => ignore animations @@ -74,11 +75,7 @@ if(!Array.indexOf){ svg.opts = opts; var ctx = target.getContext('2d'); - if (typeof(s.documentElement) != 'undefined') { - // load from xml doc - svg.loadXmlDoc(ctx, s); - } - else if (s.substr(0,1) == '<') { + if (s.substr(0,1) == '<') { // load from xml string svg.loadXml(ctx, s); } @@ -92,7 +89,6 @@ if(!Array.indexOf){ var svg = { }; svg.FRAMERATE = 30; - svg.MAX_VIRTUAL_PIXELS = 30000; // globals svg.init = function(ctx) { @@ -103,7 +99,6 @@ if(!Array.indexOf){ svg.ctx = ctx; svg.ViewPort = new (function () { this.viewPorts = []; - this.Clear = function() { this.viewPorts = []; } this.SetCurrent = function(width, height) { this.viewPorts.push({ width: width, height: height }); } this.RemoveCurrent = function() { this.viewPorts.pop(); } this.Current = function() { return this.viewPorts[this.viewPorts.length - 1]; } @@ -556,7 +551,7 @@ if(!Array.indexOf){ } } - var data = svg.trim(svg.compressSpaces(v)).split(/\s(?=[a-z])/); + var data = v.split(/\s(?=[a-z])/); for (var i=0; i0 && text[i-1]!=' ' && i0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial'; - if (typeof(font.glyphs[c]) != 'undefined') { - glyph = font.glyphs[c][arabicForm]; - if (glyph == null && font.glyphs[c].type == 'glyph') glyph = font.glyphs[c]; - } - } - else { - glyph = font.glyphs[c]; - } - if (glyph == null) glyph = font.missingGlyph; - return glyph; - } - this.renderChildren = function(ctx) { - var customFont = this.parent.style('font-family').Definition.getDefinition(); - if (customFont != null) { - var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize); - var fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle); - var text = this.getText(); - if (customFont.isRTL) text = text.split("").reverse().join(""); - - if (this.parent.style('text-anchor').value == 'middle') { - this.x = this.x - this.measureText(ctx) / 2.0; - } - - var dx = svg.ToNumberArray(this.parent.attribute('dx').value); - for (var i=0; i 0 ? node.childNodes[0].nodeValue : // element - node.text; + // TEXT ELEMENT + this.text = node.nodeType == 3 ? node.nodeValue : node.childNodes[0].nodeValue; this.getText = function() { return this.text; } @@ -2095,9 +1931,8 @@ if(!Array.indexOf){ this.base = svg.Element.ElementBase; this.base(node); - // text, or spaces then CDATA - var css = node.childNodes[0].nodeValue + (node.childNodes.length > 1 ? node.childNodes[1].nodeValue : ''); - css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm, ''); // remove comments + var css = node.childNodes[0].nodeValue; + css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(\/\/.*)/gm, ''); // remove comments css = svg.compressSpaces(css); // replace whitespace var cssDefs = css.split('}'); for (var i=0; i 0) { - var urlStart = srcs[s].indexOf('url'); - var urlEnd = srcs[s].indexOf(')', urlStart); - var url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6); - var doc = svg.parseXml(svg.ajax(url)); - var fonts = doc.getElementsByTagName('font'); - for (var f=0; f @@ -143,10 +149,12 @@ if(isset($zoom_submit)) {
+
+ + - -
-
@@ -266,6 +274,8 @@ if(isset($zoom_submit)) { + + From eaea0030641c6be215915684bcd40930ae2d61c8 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Tue, 21 Jun 2011 05:04:00 +0530 Subject: [PATCH 12/46] Added some features -> Limit on max number of rows retreived(500) -> An instruction link regarding how to use -> Resize plot by dragging it by the bottom right corner -> Two additional search criteria --- js/tbl_select.js | 9 ++++++++- js/tbl_zoom_plot.js | 36 +++++++++++++++++++++++++++++------ tbl_zoom_select.php | 46 ++++++++++++++++++++++++++++----------------- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/js/tbl_select.js b/js/tbl_select.js index 50a362d3d6..ecb1ae6851 100644 --- a/js/tbl_select.js +++ b/js/tbl_select.js @@ -32,6 +32,14 @@ $(document).ready(function() { $('#tableid_1').change(function() { $('#zoom_search_form').submit(); }) + + $('#tableid_2').change(function() { + $('#zoom_search_form').submit(); + }) + + $('#tableid_3').change(function() { + $('#zoom_search_form').submit(); + }) /** @@ -79,7 +87,6 @@ $(document).ready(function() { // found results $("#sqlqueryresults").html(response); $("#sqlqueryresults").trigger('appendAnchor'); - $("#sqlqueryresults").trigger('makegrid'); $('#tbl_search_form') // work around for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome. .slideToggle() diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 5ade2a5224..b5c2555b21 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -3,6 +3,10 @@ var chart_series; var chart_series_index = -1; $(document).ready(function() { + + + + var currentChart=null; // Get query result @@ -12,11 +16,11 @@ $(document).ready(function() { var currentSettings = { chart: { - renderTo: 'resizer', + renderTo: 'querychart', defaultSeriesType: 'scatter', zoomType: 'xy', - width:$('#resizer').width()-20, - height:$('#resizer').height()-20 + width:$('#resizer').width(), + height:$('#resizer').height() }, xAxis: { title: { text: $('#tableid_0').val() }, @@ -24,13 +28,17 @@ $(document).ready(function() { yAxis: { title: { text: $('#tableid_1').val() }, }, - title: { text: 'Scatter Plot' }, + title: { text: 'Query Results' }, + exporting: { enabled: false }, + credits: { + enabled: false + }, label: { text: $('#dataLabel').val() }, } function drawChart(noAnimation) { - currentSettings.chart.width=$('#resizer').width()-20; + currentSettings.chart.width=$('#resizer').width()-3; currentSettings.chart.height=$('#resizer').height()-20; if(currentChart!=null) currentChart.destroy(); @@ -39,9 +47,25 @@ $(document).ready(function() { currentChart = PMA_queryChart(chart_data,currentSettings); if(noAnimation) currentSettings.plotOptions.series.animation = true; } + + $('#resizer').resizable({ + resize: function() { + currentChart.setSize( + this.offsetWidth -3, + this.offsetHeight - 20, + false + ); + } + }); + drawChart(); }); +function displayHelp() { + alert("* Each point represents a data row.\n* Hovering over a point will show its label.\n* Drag and select an area in the plot to zoom into it.\n* Click reset zoom link to come back to original state.\n* Click data points to view the data row.\n* The plot can be resized by dragging it along the bottom right corner."); + +} + function in_array(element,array) { for(var i=0; i $inputs[0], 'yLabel' => $inputs[1], 'dataLabel' => $dataLabel); $result = PMA_DBI_query( $sql_query . ";" , null, PMA_DBI_QUERY_STORE); @@ -150,23 +152,33 @@ if(isset($zoom_submit)) {
- - - - - - + +
+ +"; + } + ?>
"; + echo __("Additional search criteria"); + echo "
' . "\n"; + $str .= ' ' ; } else{ - $str .= '' ; } ?> @@ -211,7 +211,7 @@ EOT; // e n u m s $enum_value=explode(', ', str_replace("'", '', substr($tbl_fields_type[$i], 5, -1))); $cnt_enum_value = count($enum_value); - $str .= '' . "\n"; + $str .= ' ' . "\n"; } else{ $str .= ' ' . "\n"; + .' size="40" class="' . $the_class . '" id="fieldID_' . $i .'" />' . "\n"; } }; return $str; diff --git a/tbl_select.php b/tbl_select.php index 7a7045cc42..af9433871d 100644 --- a/tbl_select.php +++ b/tbl_select.php @@ -71,7 +71,7 @@ echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params); ?> -
> +> diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 4ece36ea9e..57ec266027 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -17,6 +17,7 @@ require_once './libraries/relation.lib.php'; $GLOBALS['js_include'][] = 'makegrid.js'; $GLOBALS['js_include'][] = 'sql.js'; +$GLOBALS['js_include'][] = 'functions.js'; $GLOBALS['js_include'][] = 'tbl_select.js'; $GLOBALS['js_include'][] = 'tbl_zoom_plot.js'; $GLOBALS['js_include'][] = 'highcharts/highcharts.js'; @@ -33,7 +34,7 @@ $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaTh /** * Not selection yet required -> displays the selection form */ -if (true) { + // Gets some core libraries require_once './libraries/tbl_common.php'; //$err_url = 'tbl_select.php' . $err_url; @@ -65,7 +66,8 @@ if (true) { // foreign keys from innodb) $foreigners = PMA_getForeigners($db, $table); $flag = 1; - $tbl_fields_type = $tbl_fields_collation = $tbl_fields_null = array(); + $tbl_fields_type = $tbl_fields_collation = $tbl_fields_null = array(); + $maxPlotlLimit = $GLOBALS['cfg']['pmaMaxRowPlotLimit']; ?>
@@ -93,10 +95,9 @@ if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null } } - } -if(isset($zoom_submit)) { +if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_null')) { $w = $data = array(); @@ -124,10 +125,11 @@ if(isset($zoom_submit)) { if ($w) { $sql_query .= ' WHERE ' . implode(' AND ', $w); } - $sql_query .= ' LIMIT 500 '; + $sql_query .= ' LIMIT ' . $maxPlotlLimit; - if ($dataLabel == '') + if ($dataLabel == '') { $dataLabel = PMA_getDisplayField($db,$table); + } $settings = array('xLabel' => $inputs[0], 'yLabel' => $inputs[1], 'dataLabel' => $dataLabel); @@ -136,10 +138,7 @@ if(isset($zoom_submit)) { $data[] = $row; } $query_data = $data; - $scatter_plot = PMA_SVG_scatter_plot($data,$settings); -?> - - > @@ -149,21 +148,8 @@ if(isset($zoom_submit)) { /> -
- -
-
- -
-
- +
-
- - - @@ -310,9 +296,15 @@ for($i = 0 ; $i < 4 ; $i++){ } ?> + + + + + + + +
        
- -
@@ -320,10 +312,55 @@ for($i = 0 ; $i < 4 ; $i++){ value="" />
+ +
+ - - -
- Date: Mon, 4 Jul 2011 21:59:17 +0530 Subject: [PATCH 14/46] Added the Show/Hide search criteria feature --- js/tbl_zoom_plot.js | 88 +++++++++++----- tbl_zoom_select.php | 240 +++++++++++++++++++++++++------------------- 2 files changed, 199 insertions(+), 129 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 2e3fd40791..ae2143201d 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -7,23 +7,42 @@ **/ +/** + ** Display Help/Info + **/ function displayHelp() { var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp']); } +/** + ** Extend the array object for max function + ** @param array + **/ Array.max = function (array) { return Math.max.apply( Math, array ); } +/** + ** Extend the array object for min function + ** @param array + **/ Array.min = function (array) { return Math.min.apply( Math, array ); } + +/** + ** Scrolls the view to the display section + **/ function scrollToChart() { var x = $('#dataDisplay').offset().top - 100; // 100 provides buffer in viewport $('html,body').animate({scrollTop: x}, 500); } +/** + ** Displays the query result display section + ** @param modal: type of dialog + **/ function ShowDialog(modal) { $("#overlay").show(); $("#dialog").fadeIn(300); @@ -31,8 +50,12 @@ function ShowDialog(modal) { { HideDialog(); }); - } +} +/** + ** Hides the query result display section + ** @param modal : type of dialog + **/ function HideDialog() { $("#overlay").hide(); $("#dialog").fadeOut(300); @@ -49,9 +72,9 @@ $(document).ready(function() { cache: 'false' }); - var cursorMode = ($("input[name='mode']:checked").val() == 'edit') ? 'crosshair' : 'pointer'; var currentChart=null; + /** ** Form submit on field change **/ @@ -71,6 +94,9 @@ $(document).ready(function() { $('#zoom_search_form').submit(); }) + /** + ** Change mouse pointer on change of mode + */ $("input[name='mode']").change(function(){ if($("input[name='mode']:checked").val() == 'edit'){ currentSettings.plotOptions.series.cursor = 'crosshair'; @@ -84,27 +110,29 @@ $(document).ready(function() { } }); - /* - * Edit point data submit - */ - - $('#buttonID').live('click',function(event){ - - $search_form = $('#zoom_search_form'); - event.preventDefault(); - alert('Working on it!'); - //PMA_prepareForAjaxRequest($search_form); - //var str = $search_form.serialize(); - //$.post($search_form.attr('action'), str, function(response){ - // $('#sqlqueryresults').html(response); - // $("#sqlqueryresults").trigger('appendAnchor'); - - - //}); - - - }); + /** + ** Prepare a div containing a link, otherwise it's incorrectly displayed + ** after a couple of clicks + **/ + $('
') + .insertAfter('#zoom_search_form') + // don't show it until we have results on-screen + .hide(); + $('#togglesearchformlink') + .html(PMA_messages['strShowSearchCriteria']) + .bind('click', function() { + var $link = $(this); + $('#zoom_search_form').slideToggle(); + if ($link.text() == PMA_messages['strHideSearchCriteria']) { + $link.text(PMA_messages['strShowSearchCriteria']); + } else { + $link.text(PMA_messages['strHideSearchCriteria']); + } + // avoid default click action + return false; + }); + /* * Generate plot using Highcharts */ @@ -112,8 +140,17 @@ $(document).ready(function() { // Get query result var data = jQuery.parseJSON($('#querydata').html()); if (data != null) { - ShowDialog(false); - $('#resizer').height($('#dataDisplay').height() + 49); + + $('#zoom_search_form') + .slideToggle() + .hide(); + $('#togglesearchformlink') + .text(PMA_messages['strShowSearchCriteria']) + $('#togglesearchformdiv').show(); + + ShowDialog(false); + $('#resizer').height($('#dataDisplay').height() + 49); + var xLabel = $('#tableid_0').val(); var yLabel = $('#tableid_1').val(); @@ -129,6 +166,7 @@ $(document).ready(function() { // Get column names for (key in data[0]) columnNames.push(key); + // Form series $.each(data,function(key,value) { series[it] = new Object(); series[it].data = new Array(); @@ -142,6 +180,7 @@ $(document).ready(function() { it++; }); + // Set the plot settings var currentSettings = { chart: { renderTo: 'querychart', @@ -207,6 +246,7 @@ $(document).ready(function() { }); currentChart = PMA_createChart(currentSettings); + scrollToChart(); } }); diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 57ec266027..4f10b2c83f 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -18,7 +18,6 @@ require_once './libraries/relation.lib.php'; $GLOBALS['js_include'][] = 'makegrid.js'; $GLOBALS['js_include'][] = 'sql.js'; $GLOBALS['js_include'][] = 'functions.js'; -$GLOBALS['js_include'][] = 'tbl_select.js'; $GLOBALS['js_include'][] = 'tbl_zoom_plot.js'; $GLOBALS['js_include'][] = 'highcharts/highcharts.js'; /* Files required for chart exporting */ @@ -30,11 +29,10 @@ $GLOBALS['js_include'][] = 'jquery/timepicker.js'; $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage); - /** * Not selection yet required -> displays the selection form */ - + // Gets some core libraries require_once './libraries/tbl_common.php'; //$err_url = 'tbl_select.php' . $err_url; @@ -75,12 +73,11 @@ $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaTh $url_params = array(); $url_params['db'] = $db; $url_params['table'] = $table; - echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params); -?> - - -if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_null')) { + $inputs[0], 'yLabel' => $inputs[1], 'dataLabel' => $dataLabel); - $result = PMA_DBI_query( $sql_query . ";" , null, PMA_DBI_QUERY_STORE); - while ($row = PMA_DBI_fetch_assoc($result)) { - $data[] = $row; - } - $query_data = $data; - //$scatter_plot = PMA_SVG_scatter_plot($data,$settings); -} ?>
> - + /> @@ -275,10 +236,15 @@ for($i = 0 ; $i < 4 ; $i++){
+ - - - - - - - -
         - + - -
- + + + + +
> + + + + +
+ +
+ + +
- - - - - From 03a1a84b7886d7a8170d8520ad9b8948f1403d7a Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Tue, 5 Jul 2011 05:21:16 +0530 Subject: [PATCH 15/46] Test --- js/messages.php | 6 +- libraries/config.default.php | 142 +++++++++-------------------------- tbl_zoom_select.php | 5 +- 3 files changed, 42 insertions(+), 111 deletions(-) diff --git a/js/messages.php b/js/messages.php index ce56dff994..307250527e 100644 --- a/js/messages.php +++ b/js/messages.php @@ -110,8 +110,6 @@ $js_messages['strNo'] = __('No'); /* For db_stucture.js */ $js_messages['strInsertTable'] = __('Insert Table'); -$js_messages['strHideIndexes'] = __('Hide indexes'); -$js_messages['strShowIndexes'] = __('Show indexes'); /* For db_search.js */ $js_messages['strSearching'] = __('Searching'); @@ -141,7 +139,11 @@ $js_messages['strChangeTbl'] = __('Change'); $js_messages['strHideSearchCriteria'] = __('Hide search criteria'); $js_messages['strShowSearchCriteria'] = __('Show search criteria'); $js_messages['strTableSearch'] = __('Table Search'); + +/* For tbl_zoom_plot.js */ $js_messages['strZoomSearch'] = __('Zoom Search'); +$js_messages['strDisplayHelp'] = __('* Each point represents a data row.
* Hovering over a point will show its label.
* Drag and select an area in the plot to zoom into it.
* Click reset zoom link to come back to original state.
* Click data points to view the data row.
* The plot can be resized by dragging it along the bottom right corner.
'); + /* For tbl_change.js */ $js_messages['strIgnore'] = __('Ignore'); diff --git a/libraries/config.default.php b/libraries/config.default.php index 906b846ed6..3c2ba5f722 100644 --- a/libraries/config.default.php +++ b/libraries/config.default.php @@ -1117,7 +1117,6 @@ $cfg['DefaultTabDatabase'] = 'db_structure.php'; */ $cfg['DefaultTabTable'] = 'sql.php'; - /******************************************************************************* * Export defaults */ @@ -1825,7 +1824,6 @@ $cfg['Export']['xml_export_contents'] = true; */ $cfg['Export']['yaml_structure_or_data'] = 'data'; - /******************************************************************************* * Import defaults */ @@ -2312,11 +2310,6 @@ $cfg['ShowBrowseComments'] = true; */ $cfg['ShowPropertyComments']= true; -/** - * shows table display direction. - */ -$cfg['ShowDisplayDir'] = false; - /** * repeat header names every X cells? (0 = deactivate) * @@ -2418,7 +2411,6 @@ $cfg['UserprefsDisallow'] = array(); */ $cfg['UserprefsDeveloperTab'] = false; - /******************************************************************************* * Window title settings */ @@ -2529,9 +2521,7 @@ $cfg['DefaultQueryDatabase'] = ''; /******************************************************************************* * SQL Query box settings * These are the links display in all of the SQL Query boxes - */ - -/** + * * @global array $cfg['SQLQuery'] */ $cfg['SQLQuery'] = array(); @@ -2603,7 +2593,7 @@ $cfg['SaveDir'] = ''; $cfg['TempDir'] = ''; -/******************************************************************************* +/** * Misc. settings */ @@ -2645,12 +2635,7 @@ $cfg['LinkLengthLimit'] = 2000; */ $cfg['DisableMultiTableMaintenance'] = false; - /******************************************************************************* - * SQL Parser - */ - -/** * SQL Parser Settings * * @global array $cfg['SQP'] @@ -2680,10 +2665,6 @@ $cfg['SQP']['fmtIndUnit'] = 'em'; /******************************************************************************* - * SQL Validator - */ - -/** * If you wish to use the SQL Validator service, you should be aware of the * following: * All SQL statements are stored anonymously for statistical purposes. @@ -2718,10 +2699,6 @@ $cfg['SQLValidator']['password'] = ''; /******************************************************************************* * Developers ONLY! - */ - -/** - * Debugging settings * * @global array $cfg['DBG'] */ @@ -2847,19 +2824,14 @@ if ($cfg['ShowFunctionFields']) { 'CHAR', 'CHAR_LENGTH', 'COMPRESS', - 'CONNECTION_ID', 'COS', 'COT', 'CRC32', 'CURDATE', 'CURRENT_USER', 'CURTIME', - 'DATABASE', 'DATE', 'DAYNAME', - 'DAYOFMONTH', - 'DAYOFWEEK', - 'DAYOFYEAR', 'DEGREES', 'DES_DECRYPT', 'DES_ENCRYPT', @@ -2869,53 +2841,35 @@ if ($cfg['ShowFunctionFields']) { 'FROM_DAYS', 'FROM_UNIXTIME', 'HEX', - 'HOUR', 'INET_ATON', 'INET_NTOA', - 'LAST_DAY', 'LENGTH', 'LN', - 'LOAD_FILE', 'LOG', 'LOG10', 'LOG2', 'LOWER', - 'LTRIM', 'MD5', - 'MICROSECOND', - 'MINUTE', - 'MONTH', - 'MONTHNAME', 'NOW', 'OCT', 'OLD_PASSWORD', 'ORD', 'PASSWORD', - 'PI', - 'QUARTER', - 'QUOTE', 'RADIANS', 'RAND', 'REVERSE', 'ROUND', - 'RTRIM', - 'SECOND', 'SEC_TO_TIME', 'SHA1', - 'SIGN', - 'SIN', 'SOUNDEX', 'SPACE', 'SQRT', - 'SYSDATE', + 'STDDEV_POP', + 'STDDEV_SAMP', 'TAN', - 'TIME', 'TIMESTAMP', 'TIME_TO_SEC', - 'TO_DAYS', - 'TRIM', 'UNCOMPRESS', - 'UNCOMPRESSED_LENGTH', 'UNHEX', 'UNIX_TIMESTAMP', 'UPPER', @@ -2924,12 +2878,9 @@ if ($cfg['ShowFunctionFields']) { 'UTC_TIME', 'UTC_TIMESTAMP', 'UUID', - 'VERSION', - 'WEEK', - 'WEEKDAY', - 'WEEKOFYEAR', + 'VAR_POP', + 'VAR_SAMP', 'YEAR', - 'YEARWEEK', ); /** @@ -2957,29 +2908,29 @@ if ($cfg['ShowFunctionFields']) { 'TIME' => 'FUNC_DATE', 'YEAR' => 'FUNC_DATE', - 'CHAR' => 'FUNC_CHAR', - 'VARCHAR' => 'FUNC_CHAR', - 'TINYTEXT' => 'FUNC_CHAR', - 'TEXT' => 'FUNC_CHAR', - 'MEDIUMTEXT' => 'FUNC_CHAR', - 'LONGTEXT' => 'FUNC_CHAR', - 'BINARY' => 'FUNC_CHAR', - 'VARBINARY' => 'FUNC_CHAR', - 'TINYBLOB' => 'FUNC_CHAR', - 'MEDIUMBLOB' => 'FUNC_CHAR', - 'BLOB' => 'FUNC_CHAR', - 'LONGBLOB' => 'FUNC_CHAR', - 'ENUM' => '', - 'SET' => '', + 'CHAR' => 'FUNC_CHAR', + 'VARCHAR' => 'FUNC_CHAR', + 'TINYTEXT' => 'FUNC_CHAR', + 'TEXT' => 'FUNC_CHAR', + 'MEDIUMTEXT' => 'FUNC_CHAR', + 'LONGTEXT' => 'FUNC_CHAR', + 'BINARY' => 'FUNC_CHAR', + 'VARBINARY' => 'FUNC_CHAR', + 'TINYBLOB' => 'FUNC_CHAR', + 'MEDIUMBLOB' => 'FUNC_CHAR', + 'BLOB' => 'FUNC_CHAR', + 'LONGBLOB' => 'FUNC_CHAR', + 'ENUM' => '', + 'SET' => '', - 'GEOMETRY' => 'FUNC_SPATIAL', - 'POINT' => 'FUNC_SPATIAL', - 'LINESTRING' => 'FUNC_SPATIAL', - 'POLYGON' => 'FUNC_SPATIAL', - 'MULTIPOINT' => 'FUNC_SPATIAL', - 'MULTILINESTRING' => 'FUNC_SPATIAL', - 'MULTIPOLYGON' => 'FUNC_SPATIAL', - 'GEOMETRYCOLLECTION' => 'FUNC_SPATIAL', + 'GEOMETRY' => 'FUNC_SPATIAL', + 'POINT' => 'FUNC_SPATIAL', + 'LINESTRING' => 'FUNC_SPATIAL', + 'POLYGON' => 'FUNC_SPATIAL', + 'MULTIPOINT' => 'FUNC_SPATIAL', + 'MULTILINESTRING' => 'FUNC_SPATIAL', + 'MULTIPOLYGON' => 'FUNC_SPATIAL', + 'GEOMETRYCOLLECTION' => 'FUNC_SPATIAL', ); @@ -2994,27 +2945,20 @@ if ($cfg['ShowFunctionFields']) { 'CHAR', 'CURRENT_USER', 'COMPRESS', - 'DATABASE', 'DAYNAME', 'DES_DECRYPT', 'DES_ENCRYPT', 'ENCRYPT', 'HEX', 'INET_NTOA', - 'LOAD_FILE', 'LOWER', - 'LTRIM', 'MD5', - 'MONTHNAME', 'OLD_PASSWORD', 'PASSWORD', - 'QUOTE', 'REVERSE', - 'RTRIM', 'SHA1', 'SOUNDEX', 'SPACE', - 'TRIM', 'UNCOMPRESS', 'UNHEX', 'UPPER', @@ -3028,11 +2972,8 @@ if ($cfg['ShowFunctionFields']) { 'DATE', 'FROM_DAYS', 'FROM_UNIXTIME', - 'LAST_DAY', 'NOW', 'SEC_TO_TIME', - 'SYSDATE', - 'TIME', 'TIMESTAMP', 'UTC_DATE', 'UTC_TIME', @@ -3050,46 +2991,31 @@ if ($cfg['ShowFunctionFields']) { 'BIT_COUNT', 'CEILING', 'CHAR_LENGTH', - 'CONNECTION_ID', 'COS', 'COT', 'CRC32', - 'DAYOFMONTH', - 'DAYOFWEEK', - 'DAYOFYEAR', 'DEGREES', 'EXP', 'FLOOR', - 'HOUR', 'INET_ATON', 'LENGTH', 'LN', 'LOG', 'LOG2', 'LOG10', - 'MICROSECOND', - 'MINUTE', - 'MONTH', 'OCT', 'ORD', - 'PI', - 'QUARTER', 'RADIANS', 'RAND', 'ROUND', - 'SECOND', - 'SIGN', - 'SIN', 'SQRT', + 'STDDEV_POP', + 'STDDEV_SAMP', 'TAN', - 'TO_DAYS', 'TIME_TO_SEC', - 'UNCOMPRESSED_LENGTH', 'UNIX_TIMESTAMP', - 'WEEK', - 'WEEKDAY', - 'WEEKOFYEAR', - 'YEARWEEK', + 'VAR_POP', + 'VAR_SAMP', ), 'FUNC_SPATIAL' => array( @@ -3126,6 +3052,8 @@ if ($cfg['ShowFunctionFields']) { 'first_timestamp' => 'NOW', 'pk_char36' => 'UUID', ); + + } // end if /** @@ -3215,6 +3143,6 @@ $cfg['UnaryOperators'] = array( /** * Max rows retreived for zoom search */ -$cfg['pmaMaxRowPlotLimit'] = 500; +$cfg['maxRowPlotLimit'] = 500; ?> diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 4f10b2c83f..d20d61e359 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -14,6 +14,7 @@ require_once './libraries/common.inc.php'; require_once './libraries/mysql_charsets.lib.php'; require_once './libraries/tbl_select.lib.php'; require_once './libraries/relation.lib.php'; +require_once './libraries/tbl_info.inc.php'; $GLOBALS['js_include'][] = 'makegrid.js'; $GLOBALS['js_include'][] = 'sql.js'; @@ -65,7 +66,7 @@ $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaTh $foreigners = PMA_getForeigners($db, $table); $flag = 1; $tbl_fields_type = $tbl_fields_collation = $tbl_fields_null = array(); - $maxPlotlLimit = $GLOBALS['cfg']['pmaMaxRowPlotLimit']; + $maxPlotlLimit = $GLOBALS['cfg']['maxRowPlotLimit']; ?>
@@ -348,7 +349,7 @@ if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_ //JSON encode the data(query result) if(isset($zoom_submit) && !empty($data)){ ?>
-
+
From 28b142b5c314204ddf8590eb194eca2efd4061e5 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Tue, 5 Jul 2011 05:22:38 +0530 Subject: [PATCH 16/46] Made some changes -> Browse Mode makes the dialog fields disabled -> New name for max row to plot directive -> Show/Hide search criteria -> Link for displaying Help --- js/tbl_zoom_plot.js | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index ae2143201d..b48234a927 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -94,6 +94,18 @@ $(document).ready(function() { $('#zoom_search_form').submit(); }) + /* + * Disable the data info form elements if browse mode else enable on edit mode + */ + if($("input[name='mode']:checked").val() == 'edit'){ + for(var i = 4; i < 8 ; i++) + $('#fieldID_' + i).removeAttr('disabled'); + } + else{ + for(var i = 4; i < 8 ; i++) + $('#fieldID_' + i).attr('disabled', 'disabled'); + } + /** ** Change mouse pointer on change of mode */ @@ -102,24 +114,28 @@ $(document).ready(function() { currentSettings.plotOptions.series.cursor = 'crosshair'; cursorMode = 'crosshair'; currentChart = PMA_createChart(currentSettings); + for(var i = 4; i < 8 ; i++) + $('#fieldID_' + i).removeAttr('disabled'); } else{ currentSettings.plotOptions.series.cursor = 'pointer'; cursorMode = 'pointer'; currentChart = PMA_createChart(currentSettings); + for(var i = 4; i < 8 ; i++) + $('#fieldID_' + i).attr('disabled', 'disabled'); } - }); + }); - /** + /** ** Prepare a div containing a link, otherwise it's incorrectly displayed ** after a couple of clicks **/ - $('
') - .insertAfter('#zoom_search_form') - // don't show it until we have results on-screen - .hide(); + $('
') + .insertAfter('#zoom_search_form') + // don't show it until we have results on-screen + .hide(); - $('#togglesearchformlink') + $('#togglesearchformlink') .html(PMA_messages['strShowSearchCriteria']) .bind('click', function() { var $link = $(this); @@ -149,7 +165,7 @@ $(document).ready(function() { $('#togglesearchformdiv').show(); ShowDialog(false); - $('#resizer').height($('#dataDisplay').height() + 49); + $('#resizer').height($('#dataDisplay').height() + 50); var xLabel = $('#tableid_0').val(); @@ -187,7 +203,7 @@ $(document).ready(function() { defaultSeriesType: 'scatter', zoomType: 'xy', width:$('#resizer').width() -3, - height:$('#resizer').height() + height:$('#resizer').height()-20 }, credits: { enabled: false @@ -239,7 +255,7 @@ $(document).ready(function() { resize: function() { currentChart.setSize( this.offsetWidth -3, - this.offsetHeight - 20, + this.offsetHeight -20, false ); } From 41715e512a7eca3bdc83524fb1c1bf8c3f88fa51 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Thu, 7 Jul 2011 20:53:32 +0530 Subject: [PATCH 17/46] Removed mode feature, appended a missing configuration directive and changed help link duration to 10sec --- js/tbl_zoom_plot.js | 98 ++++++++++++++++++++---------------- libraries/config.default.php | 5 ++ tbl_zoom_select.php | 13 ++--- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index b48234a927..4cdd99cc72 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -11,7 +11,10 @@ ** Display Help/Info **/ function displayHelp() { - var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp']); + var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); + msgbox.click(function() { + $(this).remove(); + }); } /** @@ -73,7 +76,14 @@ $(document).ready(function() { }); var cursorMode = ($("input[name='mode']:checked").val() == 'edit') ? 'crosshair' : 'pointer'; - var currentChart=null; + var currentChart = null; + var currentData = null; + var xLabel = $('#tableid_0').val(); + var yLabel = $('#tableid_1').val(); + var dataLabel = $('#dataLabel').val(); + + // Get query result + var data = jQuery.parseJSON($('#querydata').html()); /** ** Form submit on field change @@ -94,38 +104,6 @@ $(document).ready(function() { $('#zoom_search_form').submit(); }) - /* - * Disable the data info form elements if browse mode else enable on edit mode - */ - if($("input[name='mode']:checked").val() == 'edit'){ - for(var i = 4; i < 8 ; i++) - $('#fieldID_' + i).removeAttr('disabled'); - } - else{ - for(var i = 4; i < 8 ; i++) - $('#fieldID_' + i).attr('disabled', 'disabled'); - } - - /** - ** Change mouse pointer on change of mode - */ - $("input[name='mode']").change(function(){ - if($("input[name='mode']:checked").val() == 'edit'){ - currentSettings.plotOptions.series.cursor = 'crosshair'; - cursorMode = 'crosshair'; - currentChart = PMA_createChart(currentSettings); - for(var i = 4; i < 8 ; i++) - $('#fieldID_' + i).removeAttr('disabled'); - } - else{ - currentSettings.plotOptions.series.cursor = 'pointer'; - cursorMode = 'pointer'; - currentChart = PMA_createChart(currentSettings); - for(var i = 4; i < 8 ; i++) - $('#fieldID_' + i).attr('disabled', 'disabled'); - } - }); - /** ** Prepare a div containing a link, otherwise it's incorrectly displayed ** after a couple of clicks @@ -148,13 +126,51 @@ $(document).ready(function() { // avoid default click action return false; }); - + + /* + * Handle submit of zoom_display_form + */ + + $("#zoom_display_form.ajax").live('submit', function(event) { + + //Prevent default submission of form + event.preventDefault(); + + var it = 4; + for (key in data[currentData]) { + data[currentData][key] = $('#fieldID_' + it).val(); + it++ + } + //Update the chart seiries for replot + series[currentData].data = { + name : data[currentData][dataLabel], + x : data[currentData][xLabel], + y : data[currentData][yLabel], + color : colorCodes[currentData % 8], + id : currentData, + }; + xCord[currentData] = data[currentData][xLabel] + yCord[currentData] = data[currentData][yLabel] + + currentSettings.series = series; + currentSettings.xAxis.max = Array.max(xCord) + 2; + currentSettings.xAxis.min = Array.min(xCord) - 2; + currentSettings.yAxis.max = Array.max(yCord) + 2; + currentSettings.yAxis.min = Array.min(yCord) - 2; + + currentChart = PMA_createChart(currentSettings); + $form = $('#zoom_display_form'); + $str = $form.serialize(); + $.post($form.attr('action'), $str, function(response) { + alert('Plot update done, database update remains!'); + }) + }); + + /* * Generate plot using Highcharts */ - // Get query result - var data = jQuery.parseJSON($('#querydata').html()); if (data != null) { $('#zoom_search_form') @@ -167,10 +183,6 @@ $(document).ready(function() { ShowDialog(false); $('#resizer').height($('#dataDisplay').height() + 50); - - var xLabel = $('#tableid_0').val(); - var yLabel = $('#tableid_1').val(); - var dataLabel = $('#dataLabel').val(); var columnNames = new Array(); var colorCodes = ['#FF0000','#00FFFF','#0000FF','#0000A0','#FF0080','#800080','#FFFF00','#00FF00','#FF00FF']; var series = new Array(); @@ -213,7 +225,7 @@ $(document).ready(function() { plotOptions: { series: { allowPointSelect: true, - cursor: cursorMode, + cursor: 'pointer', showInLegend: false, dataLabels: { enabled: false, @@ -227,6 +239,7 @@ $(document).ready(function() { $('#fieldID_' + j).val(data[id][key]); j++; } + currentData = id; }, } } @@ -262,7 +275,6 @@ $(document).ready(function() { }); currentChart = PMA_createChart(currentSettings); - scrollToChart(); } }); diff --git a/libraries/config.default.php b/libraries/config.default.php index 3c2ba5f722..d1f595b89a 100644 --- a/libraries/config.default.php +++ b/libraries/config.default.php @@ -2310,6 +2310,11 @@ $cfg['ShowBrowseComments'] = true; */ $cfg['ShowPropertyComments']= true; +/** + * shows table display direction. + */ +$cfg['ShowDisplayDir'] = false; + /** * repeat header names every X cells? (0 = deactivate) * diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index d20d61e359..76401d4823 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -263,14 +263,6 @@ for($i = 0 ; $i < 4 ; $i++){ } ?>
        
@@ -392,11 +384,12 @@ if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_
+
- +} +?>
Date: Fri, 8 Jul 2011 02:26:56 +0530 Subject: [PATCH 18/46] Changed text for 'How to use?' link 9$js_messages['strDisplayHelp']) --- js/messages.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/messages.php b/js/messages.php index 307250527e..ce5c85c483 100644 --- a/js/messages.php +++ b/js/messages.php @@ -142,7 +142,7 @@ $js_messages['strTableSearch'] = __('Table Search'); /* For tbl_zoom_plot.js */ $js_messages['strZoomSearch'] = __('Zoom Search'); -$js_messages['strDisplayHelp'] = __('* Each point represents a data row.
* Hovering over a point will show its label.
* Drag and select an area in the plot to zoom into it.
* Click reset zoom link to come back to original state.
* Click data points to view the data row.
* The plot can be resized by dragging it along the bottom right corner.
'); +$js_messages['strDisplayHelp'] = __('* Each point represents a data row.
* Hovering over a point will show its label.
* Drag and select an area in the plot to zoom into it.
* Click reset zoom link to come back to original state.
* Click a data point to view and possibly edit the data row.
* The plot can be resized by dragging it along the bottom right corner.
'); /* For tbl_change.js */ From c520c098ad1b4728c751d334dc356bead56a4937 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 8 Jul 2011 02:34:49 +0530 Subject: [PATCH 19/46] On submit of an edit, the data point remains selected in the plot. --- js/tbl_zoom_plot.js | 47 ++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 4cdd99cc72..d72731ce68 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -11,10 +11,10 @@ ** Display Help/Info **/ function displayHelp() { - var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); - msgbox.click(function() { - $(this).remove(); - }); + var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); + msgbox.click(function() { + $(this).remove(); + }); } /** @@ -22,7 +22,7 @@ function displayHelp() { ** @param array **/ Array.max = function (array) { - return Math.max.apply( Math, array ); + return Math.max.apply( Math, array ); } /** @@ -30,7 +30,7 @@ Array.max = function (array) { ** @param array **/ Array.min = function (array) { - return Math.min.apply( Math, array ); + return Math.min.apply( Math, array ); } @@ -47,12 +47,12 @@ function scrollToChart() { ** @param modal: type of dialog **/ function ShowDialog(modal) { - $("#overlay").show(); - $("#dialog").fadeIn(300); - $("#overlay").click(function (e) - { - HideDialog(); - }); + $("#overlay").show(); + $("#dialog").fadeIn(300); + $("#overlay").click(function (e) + { + HideDialog(); + }); } /** @@ -159,12 +159,29 @@ $(document).ready(function() { currentSettings.yAxis.min = Array.min(yCord) - 2; currentChart = PMA_createChart(currentSettings); + currentChart.series[currentData].data[0].select(); $form = $('#zoom_display_form'); $str = $form.serialize(); + alert('Working on it'); $.post($form.attr('action'), $str, function(response) { - alert('Plot update done, database update remains!'); - }) - }); + /*var sql_query = 'Update film_actor Set last_update = \'2011-01-01\' where actor_id = 1;'; + $.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('sql.php') + });//end $.post /* From 362a57f7e1663de26149f27abc4ef49144e8f744 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Sun, 10 Jul 2011 08:14:00 +0530 Subject: [PATCH 20/46] Functionality for edit data points added (primitive) --- js/tbl_zoom_plot.js | 84 +++++++++++++++++++++++++++------------------ tbl_zoom_select.php | 17 +++++++-- 2 files changed, 65 insertions(+), 36 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index d72731ce68..7282fe56b6 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -11,10 +11,10 @@ ** Display Help/Info **/ function displayHelp() { - var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); - msgbox.click(function() { - $(this).remove(); - }); + var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); + msgbox.click(function() { + $(this).remove(); + }); } /** @@ -22,7 +22,7 @@ function displayHelp() { ** @param array **/ Array.max = function (array) { - return Math.max.apply( Math, array ); + return Math.max.apply( Math, array ); } /** @@ -30,9 +30,16 @@ Array.max = function (array) { ** @param array **/ Array.min = function (array) { - return Math.min.apply( Math, array ); + return Math.min.apply( Math, array ); } +/** + ** Checks if a string contains only numeric value + ** @param n: String (to be checked) + **/ +function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); +} /** ** Scrolls the view to the display section @@ -47,12 +54,12 @@ function scrollToChart() { ** @param modal: type of dialog **/ function ShowDialog(modal) { - $("#overlay").show(); - $("#dialog").fadeIn(300); - $("#overlay").click(function (e) - { - HideDialog(); - }); + $("#overlay").show(); + $("#dialog").fadeIn(300); + $("#overlay").click(function (e) + { + HideDialog(); + }); } /** @@ -64,7 +71,6 @@ function HideDialog() { $("#dialog").fadeOut(300); } - $(document).ready(function() { /** @@ -138,7 +144,8 @@ $(document).ready(function() { var it = 4; for (key in data[currentData]) { - data[currentData][key] = $('#fieldID_' + it).val(); + if (key != 'where_clause') + data[currentData][key] = $('#fieldID_' + it).val(); it++ } //Update the chart seiries for replot @@ -160,29 +167,40 @@ $(document).ready(function() { currentChart = PMA_createChart(currentSettings); currentChart.series[currentData].data[0].select(); - $form = $('#zoom_display_form'); - $str = $form.serialize(); - alert('Working on it'); - $.post($form.attr('action'), $str, function(response) { - /*var sql_query = 'Update film_actor Set last_update = \'2011-01-01\' where actor_id = 1;'; - $.post('sql.php', { - 'token' : window.parent.token, - 'db' : window.parent.db, - 'ajax_request' : true, - 'sql_query' : sql_query, - 'inline_edit' : false + + //Generate SQL query for update + var sql_query = 'UPDATE `' + window.parent.table + '` SET '; + $.each(data[currentData],function(index, value) { + if(index != 'where_clause') { + sql_query += '`' + index + '`=' + if(!isNumeric(value)) + sql_query += '\'' + value.replace(/'/g, "''") + '\' ,' + else + sql_query += value.replace(/'/g, "''") + ' ,' + + } + else { + sql_query = sql_query.substring(0, sql_query.length - 1); + sql_query += ' WHERE ' + PMA_urldecode(value); + } + }); + //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'); + $('#sqlqueryresults').html(data.sql_query); + $("#sqlqueryresults").trigger('appendAnchor'); } - else - PMA_ajaxShowMessage(data.error); - })*/ + else + PMA_ajaxShowMessage(data.error); + }) - })//end $.post('sql.php') - });//end $.post - + })//end $.post('sql.php') /* * Generate plot using Highcharts diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 76401d4823..e7c24e1a87 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -28,8 +28,8 @@ $GLOBALS['js_include'][] = 'canvg/rgbcolor.js'; $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js'; $GLOBALS['js_include'][] = 'jquery/timepicker.js'; -$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage); +$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage); /** * Not selection yet required -> displays the selection form */ @@ -69,6 +69,7 @@ $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaTh $maxPlotlLimit = $GLOBALS['cfg']['maxRowPlotLimit']; ?> +
-
+ From d90a58d06150f27f008d63c9fee8b92e56afaeea Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Sun, 10 Jul 2011 08:37:15 +0530 Subject: [PATCH 21/46] Some indentation errors fixed from previous commit --- js/tbl_zoom_plot.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 7282fe56b6..87aceedc1a 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -11,10 +11,10 @@ ** Display Help/Info **/ function displayHelp() { - var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); - msgbox.click(function() { - $(this).remove(); - }); + var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); + msgbox.click(function() { + $(this).remove(); + }); } /** @@ -22,7 +22,7 @@ function displayHelp() { ** @param array **/ Array.max = function (array) { - return Math.max.apply( Math, array ); + return Math.max.apply( Math, array ); } /** @@ -30,7 +30,7 @@ Array.max = function (array) { ** @param array **/ Array.min = function (array) { - return Math.min.apply( Math, array ); + return Math.min.apply( Math, array ); } /** From cdf70921a4976d6fbd79793ba7fa2b5c873bbe2b Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Tue, 12 Jul 2011 06:51:20 +0530 Subject: [PATCH 22/46] Fixed misfunction of edit mode --- js/tbl_zoom_plot.js | 119 +++++++++++++++++++++++++++----------------- tbl_zoom_select.php | 4 +- 2 files changed, 75 insertions(+), 48 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 87aceedc1a..ddfb18c1de 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -11,10 +11,10 @@ ** Display Help/Info **/ function displayHelp() { - var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); - msgbox.click(function() { - $(this).remove(); - }); + var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000); + msgbox.click(function() { + $(this).remove(); + }); } /** @@ -22,7 +22,7 @@ function displayHelp() { ** @param array **/ Array.max = function (array) { - return Math.max.apply( Math, array ); + return Math.max.apply( Math, array ); } /** @@ -30,7 +30,7 @@ Array.max = function (array) { ** @param array **/ Array.min = function (array) { - return Math.min.apply( Math, array ); + return Math.min.apply( Math, array ); } /** @@ -41,6 +41,18 @@ function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } +/** + ** Checks if an object is empty + ** @param n: Object (to be checked) + **/ +function isEmpty(obj) { + var name; + for (name in obj) { + return false; + } + return true; +} + /** ** Scrolls the view to the display section **/ @@ -142,13 +154,22 @@ $(document).ready(function() { //Prevent default submission of form event.preventDefault(); + //Update the data, find changed values + var newValues = new Array();//Stores the values changed from original var it = 4; for (key in data[currentData]) { - if (key != 'where_clause') - data[currentData][key] = $('#fieldID_' + it).val(); + if (key != 'where_clause'){ + var oldVal = data[currentData][key]; + var newVal = ($('#fields_null_id_' + it).attr('checked')) ? null : $('#fieldID_' + it).val(); + if (oldVal != newVal){ + data[currentData][key] = newVal; + newValues[key] = newVal; + } + } it++ - } - //Update the chart seiries for replot + }//End data update + + //Update the chart series and replot series[currentData].data = { name : data[currentData][dataLabel], x : data[currentData][xLabel], @@ -156,6 +177,7 @@ $(document).ready(function() { color : colorCodes[currentData % 8], id : currentData, }; + xCord[currentData] = data[currentData][xLabel] yCord[currentData] = data[currentData][yLabel] @@ -165,49 +187,49 @@ $(document).ready(function() { currentSettings.yAxis.max = Array.max(yCord) + 2; currentSettings.yAxis.min = Array.min(yCord) - 2; - currentChart = PMA_createChart(currentSettings); + currentChart = PMA_createChart(currentSettings); currentChart.series[currentData].data[0].select(); - - //Generate SQL query for update - var sql_query = 'UPDATE `' + window.parent.table + '` SET '; - $.each(data[currentData],function(index, value) { - if(index != 'where_clause') { - sql_query += '`' + index + '`=' - if(!isNumeric(value)) - sql_query += '\'' + value.replace(/'/g, "''") + '\' ,' - else - sql_query += value.replace(/'/g, "''") + ' ,' + //End plot update - } - else { - sql_query = sql_query.substring(0, sql_query.length - 1); - sql_query += ' WHERE ' + PMA_urldecode(value); - } - }); - //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'); + //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 + ' ,'; } - else - PMA_ajaxShowMessage(data.error); - }) - - })//end $.post('sql.php') + } + 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 + });//End submit handler /* * Generate plot using Highcharts */ if (data != null) { - $('#zoom_search_form') .slideToggle() .hide(); @@ -216,7 +238,7 @@ $(document).ready(function() { $('#togglesearchformdiv').show(); ShowDialog(false); - $('#resizer').height($('#dataDisplay').height() + 50); + //$('#resizer').height($('#dataDisplay').height() + 50); var columnNames = new Array(); var colorCodes = ['#FF0000','#00FFFF','#0000FF','#0000A0','#FF0080','#800080','#FFFF00','#00FF00','#FF00FF']; @@ -270,8 +292,11 @@ $(document).ready(function() { click: function() { var id = this.id; var j = 4; - for( key in data[id]){ - $('#fieldID_' + j).val(data[id][key]); + for( key in data[id]) { + if (data[id][key] == null) + $('#fields_null_id_' + j).attr('checked', true); + else + $('#fieldID_' + j).val(data[id][key]); j++; } currentData = id; diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index e7c24e1a87..a44b167499 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -351,7 +351,7 @@ if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_ -
+
- +
+
From bedd413217a87770852671c4a2b211ca067df5e0 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 22 Jul 2011 17:50:09 +0530 Subject: [PATCH 29/46] Resolved merge conflict --- js/highcharts/exporting.js | 13 +++++++++++-- js/highcharts/highcharts.js | 5 ----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/js/highcharts/exporting.js b/js/highcharts/exporting.js index 301e5e2475..cb04357b32 100644 --- a/js/highcharts/exporting.js +++ b/js/highcharts/exporting.js @@ -281,7 +281,8 @@ extend(Chart.prototype, { canvas=createElement('canvas'); $('body').append(canvas); - $(canvas).hide(); + $(canvas).css('position','absolute'); + $(canvas).css('left','-10000px'); var submitData = function(chartData) { // merge the options @@ -320,11 +321,19 @@ extend(Chart.prototype, { if(options && options.type=='image/svg+xml') { submitData(chart.getSVG(chartOptions)); } else { + if (typeof FlashCanvas != "undefined") { + FlashCanvas.initElement(canvas); + } + // Generate data uri and submit once done canvg(canvas, chart.getSVG(chartOptions),{ ignoreAnimation:true, ignoreMouse:true, - renderCallback:function() { submitData(canvas.toDataURL()); } + renderCallback:function() { + // IE8 fix: flashcanvas doesn't update the canvas immediately, thus requiring setTimeout. + // See also http://groups.google.com/group/flashcanvas/browse_thread/thread/e36ff7a03e1bfb0a + setTimeout(function() { submitData(canvas.toDataURL()); }, 100); + } }); } }, diff --git a/js/highcharts/highcharts.js b/js/highcharts/highcharts.js index fee96bf1b3..b3b8e9d571 100644 --- a/js/highcharts/highcharts.js +++ b/js/highcharts/highcharts.js @@ -2305,15 +2305,10 @@ SVGRenderer.prototype = { // Webkit and opera sometimes return 'normal' as the line height. In that // case, webkit uses offsetHeight, while Opera falls back to 18 -<<<<<<< HEAD - lineHeight = pInt(window.getComputedStyle(lastLine, null).getPropertyValue('line-height')); - if (isNaN(lineHeight)) { -======= lineHeight = win[GET_COMPUTED_STYLE] && win[GET_COMPUTED_STYLE](lastLine, null).getPropertyValue('line-height'); if (!lineHeight || isNaN(lineHeight)) { ->>>>>>> phpmyadmin/master lineHeight = textLineHeight || lastLine.offsetHeight || 18; } attr(tspan, 'dy', lineHeight); From 95ea722d73fc635b4b27c6731aeedfd430628ce8 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 22 Jul 2011 17:51:53 +0530 Subject: [PATCH 30/46] Fixed redirection issue on tbl_zoom_select.php page --- libraries/common.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/common.inc.php b/libraries/common.inc.php index 53cde17982..cb6a8e3dd7 100644 --- a/libraries/common.inc.php +++ b/libraries/common.inc.php @@ -413,6 +413,7 @@ $goto_whitelist = array( 'tbl_replace.php', 'tbl_row_action.php', 'tbl_select.php', + 'tbl_zoom_select.php', //'themes.php', 'transformation_overview.php', 'transformation_wrapper.php', From 6cc3ff46f853960bdc90eb00fd595591e6a26f2e Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 22 Jul 2011 17:53:13 +0530 Subject: [PATCH 31/46] Data point content is now displayed as a dialog box which opens on clicking a point and closes on finishing an edit --- js/tbl_zoom_plot.js | 43 +++++++++++++++---------------------------- tbl_zoom_select.php | 16 ++++++---------- 2 files changed, 21 insertions(+), 38 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index c853a65167..05a9e49b02 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -61,28 +61,6 @@ function scrollToChart() { $('html,body').animate({scrollTop: x}, 500); } -/** - ** Displays the query result display section - ** @param modal: type of dialog - **/ -function ShowDialog(modal) { - $("#overlay").show(); - $("#dialog").fadeIn(300); - $("#overlay").click(function (e) - { - HideDialog(); - }); -} - -/** - ** Hides the query result display section - ** @param modal : type of dialog - **/ -function HideDialog() { - $("#overlay").hide(); - $("#dialog").fadeOut(300); -} - $(document).ready(function() { /** @@ -144,12 +122,23 @@ $(document).ready(function() { // avoid default click action return false; }); - + + /** + ** Set dialog properties for the data display form + **/ + $("#dataDisplay").dialog({ + autoOpen: false, + 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 */ - $("#zoom_display_form.ajax").live('submit', function(event) { + $("#submitForm").click(function(event) { //Prevent default submission of form event.preventDefault(); @@ -223,6 +212,7 @@ $(document).ready(function() { PMA_ajaxShowMessage(data.error); })//End $.post }//End database update + $("#dataDisplay").dialog("close"); });//End submit handler /* @@ -237,9 +227,6 @@ $(document).ready(function() { .text(PMA_messages['strShowSearchCriteria']) $('#togglesearchformdiv').show(); - ShowDialog(false); - //$('#resizer').height($('#dataDisplay').height() + 50); - var columnNames = new Array(); var colorCodes = ['#FF0000','#00FFFF','#0000FF','#0000A0','#FF0080','#800080','#FFFF00','#00FF00','#FF00FF']; var series = new Array(); @@ -300,6 +287,7 @@ $(document).ready(function() { j++; } currentData = id; + $("#dataDisplay").dialog("open"); }, } } @@ -315,7 +303,6 @@ $(document).ready(function() { xAxis: { type: 'linear', title: { text: $('#tableid_0').val() }, - type: 'linear', max: Array.max(xCord) + 2, min: Array.min(xCord) - 2 }, diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 81327b3496..431f4614cb 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -22,7 +22,6 @@ $GLOBALS['js_include'][] = 'functions.js'; $GLOBALS['js_include'][] = 'tbl_zoom_plot.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'; @@ -233,7 +232,7 @@ for($i = 0 ; $i < 4 ; $i++){ - @@ -349,14 +348,13 @@ if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_ -
-
From e09759bef84ae8113f2e468117be66fb43d4b932 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Mon, 25 Jul 2011 04:50:47 +0530 Subject: [PATCH 32/46] Added support for ploting strings(char,varchar,enums) --- js/tbl_zoom_plot.js | 144 +++++++++++++++++++++++++++++++++++--------- tbl_zoom_select.php | 1 + 2 files changed, 118 insertions(+), 27 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 05a9e49b02..28f70ebb74 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -53,6 +53,32 @@ function isEmpty(obj) { return true; } +/** + ** 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) + return 'numeric'; + else if(field.toString().search(/time/i) != -1) + return 'text'; + else + return 'text'; +} +/** + ** Converts a categorical array into numeric array + ** @param array categorical values array + **/ +function getCord(arr) { + var newCord = new Array(); + var original = $.extend(true,[],arr); + var arr = jQuery.unique(arr).sort(); + $.each(original, function(index,value) { + newCord.push(jQuery.inArray(value,arr)); + }); + return [newCord,arr]; +} + /** ** Scrolls the view to the display section **/ @@ -76,6 +102,8 @@ $(document).ready(function() { var currentData = null; var xLabel = $('#tableid_0').val(); var yLabel = $('#tableid_1').val(); + var xType = $('#types_0').val(); + var yType = $('#types_1').val(); var dataLabel = $('#dataLabel').val(); // Get query result @@ -159,11 +187,11 @@ $(document).ready(function() { }//End data update //Update the chart series and replot - series[currentData].data = { + series[0].data[currentData] = { name : data[currentData][dataLabel], x : data[currentData][xLabel], y : data[currentData][yLabel], - color : colorCodes[currentData % 8], + marker: {fillColor: colorCodes[it % 8]}, id : currentData, }; @@ -177,7 +205,7 @@ $(document).ready(function() { currentSettings.yAxis.min = Array.min(yCord) - 2; currentChart = PMA_createChart(currentSettings); - currentChart.series[currentData].data[0].select(); + currentChart.series[0].data[currentData].select(); //End plot update //Generate SQL query for update @@ -232,31 +260,16 @@ $(document).ready(function() { var series = new Array(); var xCord = new Array(); var yCord = new Array(); + var xCat = new Array(); + var yCat = new Array(); var temp; var it = 0; - // Get column names - for (key in data[0]) columnNames.push(key); - - // Form series - $.each(data,function(key,value) { - series[it] = new Object(); - series[it].data = new Array(); - series[it].color = colorCodes[it % 8]; - series[it].marker = { - symbol: 'circle' - }; - xCord.push(value[xLabel]); - yCord.push(value[yLabel]); - series[it].data.push({ name: value[dataLabel], x:value[xLabel], y:value[yLabel], color: colorCodes[it % 8], id: it } ); - it++; - }); - - // Set the plot settings + // Set the basic plot settings var currentSettings = { chart: { renderTo: 'querychart', - defaultSeriesType: 'scatter', + type: 'scatter', zoomType: 'xy', width:$('#resizer').width() -3, height:$('#resizer').height()-20 @@ -298,18 +311,13 @@ $(document).ready(function() { return this.point.name; } }, - series: series, title: { text: 'Query Results' }, xAxis: { type: 'linear', title: { text: $('#tableid_0').val() }, - max: Array.max(xCord) + 2, - min: Array.min(xCord) - 2 }, yAxis: { title: { text: $('#tableid_1').val() }, - max: Array.max(yCord) + 3, - min: Array.min(yCord) - 2 }, } @@ -323,6 +331,88 @@ $(document).ready(function() { } }); + xType = getType(xType); + yType = getType(yType); + + // Formulate series data for plot + series[0] = new Object(); + series[0].data = new Array(); + series[0].marker = { + symbol: 'circle' + }; + if (xType == 'numeric' && yType == 'numeric') { + $.each(data,function(key,value) { + series[0].data.push({ name: value[dataLabel], x: value[xLabel], y: value[yLabel], marker: {fillColor: colorCodes[it % 8]} , id: it } ); + xCord.push(value[xLabel]); + yCord.push(value[yLabel]); + it++; + }); + currentSettings.xAxis.max = Array.max(xCord) + 2 + currentSettings.xAxis.min = Array.min(xCord) - 2 + currentSettings.yAxis.max = Array.max(yCord) + 3 + currentSettings.yAxis.min = Array.min(yCord) - 2 + } + + else if (xType =='text' && yType =='numeric') { + $.each(data,function(key,value) { + xCord.push(value[xLabel]); + yCord.push(value[yLabel]); + }); + temp = getCord(xCord); + $.each(data,function(key,value) { + series[0].data.push({ name: value[dataLabel], x: temp[0][it], y: value[yLabel], marker: {fillColor: colorCodes[it % 8]} , id: it } ); + it++; + }); + currentSettings.yAxis.max = Array.max(yCord) + 3 + currentSettings.yAxis.min = Array.min(yCord) - 2 + currentSettings.xAxis.labels = { formatter : function() { + return temp[1][this.value]; + } + } + } + + else if (xType =='numeric' && yType =='text') { + $.each(data,function(key,value) { + xCord.push(value[xLabel]); + yCord.push(value[yLabel]); + }); + temp = getCord(yCord); + $.each(data,function(key,value) { + series[0].data.push({ name: value[dataLabel], x: temp[0][it], y: value[xLabel], marker: {fillColor: colorCodes[it % 8]} , id: it } ); + it++; + }); + currentSettings.yAxis.max = Array.max(xCord) + 3 + currentSettings.yAxis.min = Array.min(xCord) - 2 + currentSettings.xAxis.labels = { formatter : function() { + return temp[1][this.value]; + } + } + currentSettings.xAxis.title.text = $('#tableid_1').val() + currentSettings.yAxis.title.text = $('#tableid_0').val() + } + + else if (xType =='text' && yType =='text') { + $.each(data,function(key,value) { + xCord.push(value[xLabel]); + yCord.push(value[yLabel]); + }); + temp = getCord(xCord); + var temp2 = getCord(yCord); + $.each(data,function(key,value) { + series[0].data.push({ name: value[dataLabel], x: temp[0][it], y: temp2[0][it], marker: {fillColor: colorCodes[it % 8]} , id: it } ); + it++; + }); + currentSettings.xAxis.labels = { formatter : function() { + return temp[1][this.value]; + } + } + currentSettings.yAxis.labels = { formatter : function() { + return temp2[1][this.value]; + } + } + } + + currentSettings.series = series; currentChart = PMA_createChart(currentSettings); scrollToChart(); } diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 431f4614cb..6cf02825a4 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -22,6 +22,7 @@ $GLOBALS['js_include'][] = 'functions.js'; $GLOBALS['js_include'][] = 'tbl_zoom_plot.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'; From d9486e259721b812cb0cd56ca057e55359250cc9 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Mon, 25 Jul 2011 19:45:00 +0530 Subject: [PATCH 33/46] Validations for input form submit --- js/messages.php | 21 ++++++++++++--------- js/tbl_zoom_plot.js | 12 +++++++++++- tbl_zoom_select.php | 6 +++--- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/js/messages.php b/js/messages.php index 90048d1b44..17d0fad6c6 100644 --- a/js/messages.php +++ b/js/messages.php @@ -137,9 +137,6 @@ $js_messages['strChartTitle'] = __('Chart Title'); $js_messages['strDifferential'] = __('Differential'); $js_messages['strDividedBy'] = __('Divided by %s:'); -$js_messages['strSelectedTimeRange'] = __('Selected time range:'); -$js_messages['strGroupInserts'] = __('Group together INSERTs into same table'); -$js_messages['strLogAnalyseInfo'] = __('

Choose from which log you want the statistics to be generated from.

Results are grouped by query text.'); $js_messages['strFromSlowLog'] = __('From slow log'); $js_messages['strFromGeneralLog'] = __('From general log'); $js_messages['strAnalysingLogs'] = __('Analysing & loading logs. This may take a while.'); @@ -150,6 +147,15 @@ $js_messages['strLogDataLoaded'] = __('Log data loaded. Queries executed in this $js_messages['strJumpToTable'] = __('Jump to Log table'); $js_messages['strNoDataFound'] = __('Log analysed, but not data found in this time span.'); +/* l10n: A collection of available filters */ +$js_messages['strFilters'] = __('Filters'); +/* l10n: Filter as in "Start Filtering" */ +$js_messages['strFilter'] = __('Filter'); +$js_messages['strFilterByWordRegexp'] = __('Filter queries by word/regexp:'); +$js_messages['strIgnoreWhereAndGroup'] = __('Group queries, ignoring variable data in WHERE statements'); +$js_messages['strSumRows'] = __('Sum of grouped rows:'); +$js_messages['strTotal'] = __('Total:'); + /* For inline query editing */ $js_messages['strGo'] = __('Go'); $js_messages['strCancel'] = __('Cancel'); @@ -174,6 +180,8 @@ $js_messages['strNo'] = __('No'); /* For db_stucture.js */ $js_messages['strInsertTable'] = __('Insert Table'); +$js_messages['strHideIndexes'] = __('Hide indexes'); +$js_messages['strShowIndexes'] = __('Show indexes'); /* For db_search.js */ $js_messages['strSearching'] = __('Searching'); @@ -197,16 +205,11 @@ $js_messages['strSave'] = __('Save'); $js_messages['strHide'] = __('Hide'); $js_messages['strNoRowSelected'] = __('No rows selected'); $js_messages['strChangeTbl'] = __('Change'); +$js_messages['strQueryExecutionTime'] = __('Query execution time'); /* For tbl_select.js */ $js_messages['strHideSearchCriteria'] = __('Hide search criteria'); $js_messages['strShowSearchCriteria'] = __('Show search criteria'); -$js_messages['strTableSearch'] = __('Table Search'); - -/* For tbl_zoom_plot.js */ -$js_messages['strZoomSearch'] = __('Zoom Search'); -$js_messages['strDisplayHelp'] = __('* Each point represents a data row.
* Hovering over a point will show its label.
* Drag and select an area in the plot to zoom into it.
* Click reset zoom link to come back to original state.
* Click a data point to view and possibly edit the data row.
* The plot can be resized by dragging it along the bottom right corner.
'); - /* For tbl_change.js */ $js_messages['strIgnore'] = __('Ignore'); diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 28f70ebb74..05e5b8537e 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -110,7 +110,7 @@ $(document).ready(function() { var data = jQuery.parseJSON($('#querydata').html()); /** - ** Form submit on field change + ** Input form submit on field change **/ $('#tableid_0').change(function() { $('#zoom_search_form').submit(); @@ -128,6 +128,16 @@ $(document).ready(function() { $('#zoom_search_form').submit(); }) + /** + * 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) + PMA_ajaxShowMessage(PMA_messages['strSameInputs']); + }); + /** ** Prepare a div containing a link, otherwise it's incorrectly displayed ** after a couple of clicks diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 6cf02825a4..6bc5d6016c 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -116,7 +116,7 @@ if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null
- + @@ -279,7 +279,7 @@ for($i = 0 ; $i < 4 ; $i++){
- +
@@ -289,7 +289,7 @@ for($i = 0 ; $i < 4 ; $i++){ * Handle the input criteria and gerate the query result * Form for displaying query results */ -if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_null')) { +if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_null') && $inputs[0] != $inputs[1]) { /* * Query generation part From 9388cd35b643ea65473ffa95cdf21213bcc4785f Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Mon, 25 Jul 2011 19:50:02 +0530 Subject: [PATCH 34/46] Re:Validations for input form submit (missed addidng messages.php file) --- js/messages.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/js/messages.php b/js/messages.php index 17d0fad6c6..2179035b8a 100644 --- a/js/messages.php +++ b/js/messages.php @@ -211,6 +211,12 @@ $js_messages['strQueryExecutionTime'] = __('Query execution time'); $js_messages['strHideSearchCriteria'] = __('Hide search criteria'); $js_messages['strShowSearchCriteria'] = __('Show search criteria'); +/* For tbl_zoom_plot.js */ +$js_messages['strZoomSearch'] = __('Zoom Search'); +$js_messages['strDisplayHelp'] = __('* Each point represents a data row.
* Hovering over a point will show its label.
* Drag and select an area in the plot to zoom into it.
* Click reset zoom link to come back to original state.
* Click a data point to view and possibly edit the data row.
* The plot can be resized by dragging it along the bottom right corner.
'); +$js_messages['strInputNull'] = __('Select two columns'); +$js_messages['strSameInputs'] = __('Select two different columns'); + /* For tbl_change.js */ $js_messages['strIgnore'] = __('Ignore'); From e83f3acd26fbfb51366cae9b184e69e5376ae10d Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Sun, 31 Jul 2011 12:35:07 +0530 Subject: [PATCH 35/46] Added to 'How to use' message content, strings are converted into integers for plotting purpose. --- js/messages.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/messages.php b/js/messages.php index a66e20b8db..4c10d2fee8 100644 --- a/js/messages.php +++ b/js/messages.php @@ -213,7 +213,7 @@ $js_messages['strShowSearchCriteria'] = __('Show search criteria'); /* For tbl_zoom_plot.js */ $js_messages['strZoomSearch'] = __('Zoom Search'); -$js_messages['strDisplayHelp'] = __('* Each point represents a data row.
* Hovering over a point will show its label.
* Drag and select an area in the plot to zoom into it.
* Click reset zoom link to come back to original state.
* Click a data point to view and possibly edit the data row.
* The plot can be resized by dragging it along the bottom right corner.
'); +$js_messages['strDisplayHelp'] = __('* Each point represents a data row.
* Hovering over a point will show its label.
* Drag and select an area in the plot to zoom into it.
* Click reset zoom link to come back to original state.
* Click a data point to view and possibly edit the data row.
* The plot can be resized by dragging it along the bottom right corner.
* Strings are converted into integer for plotting'); $js_messages['strInputNull'] = __('Select two columns'); $js_messages['strSameInputs'] = __('Select two different columns'); From df0848fa9c94a100d153cb4500d723566e8c25c0 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Sun, 31 Jul 2011 12:41:09 +0530 Subject: [PATCH 36/46] String plotting: truncated axis labels with length greater than 10. --- js/tbl_zoom_plot.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 05e5b8537e..d19e01fa1f 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -376,7 +376,10 @@ $(document).ready(function() { currentSettings.yAxis.max = Array.max(yCord) + 3 currentSettings.yAxis.min = Array.min(yCord) - 2 currentSettings.xAxis.labels = { formatter : function() { - return temp[1][this.value]; + if(temp[1][this.value] && temp[1][this.value].length > 10) + return temp[1][this.value].substring(0,10); + else + return temp[1][this.value]; } } } @@ -394,7 +397,10 @@ $(document).ready(function() { currentSettings.yAxis.max = Array.max(xCord) + 3 currentSettings.yAxis.min = Array.min(xCord) - 2 currentSettings.xAxis.labels = { formatter : function() { - return temp[1][this.value]; + if(temp[1][this.value] && temp[1][this.value].length > 10) + return temp[1][this.value].substring(0,10); + else + return temp[1][this.value]; } } currentSettings.xAxis.title.text = $('#tableid_1').val() @@ -413,11 +419,17 @@ $(document).ready(function() { it++; }); currentSettings.xAxis.labels = { formatter : function() { - return temp[1][this.value]; + if(temp[1][this.value] && temp[1][this.value].length > 10) + return temp[1][this.value].substring(0,10); + else + return temp[1][this.value]; } } currentSettings.yAxis.labels = { formatter : function() { - return temp2[1][this.value]; + if(temp[1][this.value] && temp[1][this.value].length > 10) + return temp[1][this.value].substring(0,10); + else + return temp2[1][this.value]; } } } From 00c420c74b4663fddf0b5fc47ac50fdd15dd23c6 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Sun, 31 Jul 2011 12:50:24 +0530 Subject: [PATCH 37/46] Edit feature with support for string plot. Also made some optimizations to avoid unnecesarry replot --- js/tbl_zoom_plot.js | 160 +++++++++++++++++++++++++++++++------------- 1 file changed, 112 insertions(+), 48 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index d19e01fa1f..6060969ee6 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -76,7 +76,7 @@ function getCord(arr) { $.each(original, function(index,value) { newCord.push(jQuery.inArray(value,arr)); }); - return [newCord,arr]; + return [newCord,arr,original]; } /** @@ -184,6 +184,8 @@ $(document).ready(function() { //Update the data, find changed values var newValues = new Array();//Stores the values changed from original var it = 4; + var xChange = false; + var yChange = false; for (key in data[currentData]) { if (key != 'where_clause'){ var oldVal = data[currentData][key]; @@ -191,31 +193,90 @@ $(document).ready(function() { if (oldVal != newVal){ data[currentData][key] = newVal; newValues[key] = newVal; + if(key == xLabel) + xChange = true; + else if(key == yLabel) + yChange = true; } } it++ }//End data update //Update the chart series and replot - series[0].data[currentData] = { - name : data[currentData][dataLabel], - x : data[currentData][xLabel], - y : data[currentData][yLabel], - marker: {fillColor: colorCodes[it % 8]}, - id : currentData, - }; + if (xChange || yChange) { + 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] = data[currentData][xLabel]; + if(xType == 'numeric') { + currentChart.series[0].data[currentData].update({ x : data[currentData][xLabel] }); + currentChart.xAxis[0].setExtremes(Array.min(xCord) - 2,Array.max(xCord) + 2); + } + else { + var tempX = getCord(xCord); + var tempY = getCord(yCord); + var i = 0; + newSeries[0].data = new Array(); + xCord = tempX[2]; + yCord = tempY[2]; - xCord[currentData] = data[currentData][xLabel] - yCord[currentData] = data[currentData][yLabel] + $.each(data,function(key,value) { + if(yType == 'numeric') + 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++; + }); + 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; + currentChart = PMA_createChart(currentSettings); + } - currentSettings.series = series; - currentSettings.xAxis.max = Array.max(xCord) + 2; - currentSettings.xAxis.min = Array.min(xCord) - 2; - currentSettings.yAxis.max = Array.max(yCord) + 2; - currentSettings.yAxis.min = Array.min(yCord) - 2; - - currentChart = PMA_createChart(currentSettings); - currentChart.series[0].data[currentData].select(); + } + if(yChange) { + yCord[currentData] = data[currentData][yLabel]; + if(yType == 'numeric') { + currentChart.series[0].data[currentData].update({ y : data[currentData][yLabel] }); + currentChart.yAxis[0].setExtremes(Array.min(yCord) - 2,Array.max(yCord) + 2); + } + 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 == 'numeric') + newSeries[0].data.push({ name: value[dataLabel], x: value[xLabel], y: tempY[0][i], 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++; + }); + 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(); + } //End plot update //Generate SQL query for update @@ -272,7 +333,7 @@ $(document).ready(function() { var yCord = new Array(); var xCat = new Array(); var yCat = new Array(); - var temp; + var tempX, tempY; var it = 0; // Set the basic plot settings @@ -368,20 +429,21 @@ $(document).ready(function() { xCord.push(value[xLabel]); yCord.push(value[yLabel]); }); - temp = getCord(xCord); + tempX = getCord(xCord); $.each(data,function(key,value) { - series[0].data.push({ name: value[dataLabel], x: temp[0][it], y: value[yLabel], marker: {fillColor: colorCodes[it % 8]} , id: it } ); + series[0].data.push({ name: value[dataLabel], x: tempX[0][it], y: value[yLabel], marker: {fillColor: colorCodes[it % 8]} , id: it } ); it++; }); currentSettings.yAxis.max = Array.max(yCord) + 3 currentSettings.yAxis.min = Array.min(yCord) - 2 currentSettings.xAxis.labels = { formatter : function() { - if(temp[1][this.value] && temp[1][this.value].length > 10) - return temp[1][this.value].substring(0,10); - else - return temp[1][this.value]; - } + 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]; + } } + xCord = tempX[2]; } else if (xType =='numeric' && yType =='text') { @@ -389,22 +451,21 @@ $(document).ready(function() { xCord.push(value[xLabel]); yCord.push(value[yLabel]); }); - temp = getCord(yCord); + tempY = getCord(yCord); $.each(data,function(key,value) { - series[0].data.push({ name: value[dataLabel], x: temp[0][it], y: value[xLabel], marker: {fillColor: colorCodes[it % 8]} , id: it } ); + series[0].data.push({ name: value[dataLabel], y: tempY[0][it], x: value[xLabel], marker: {fillColor: colorCodes[it % 8]} , id: it } ); it++; }); - currentSettings.yAxis.max = Array.max(xCord) + 3 - currentSettings.yAxis.min = Array.min(xCord) - 2 - currentSettings.xAxis.labels = { formatter : function() { - if(temp[1][this.value] && temp[1][this.value].length > 10) - return temp[1][this.value].substring(0,10); - else - return temp[1][this.value]; + currentSettings.xAxis.max = Array.max(xCord) + 3 + currentSettings.xAxis.min = Array.min(xCord) - 2 + 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.xAxis.title.text = $('#tableid_1').val() - currentSettings.yAxis.title.text = $('#tableid_0').val() + yCord = tempY[2]; } else if (xType =='text' && yType =='text') { @@ -412,26 +473,29 @@ $(document).ready(function() { xCord.push(value[xLabel]); yCord.push(value[yLabel]); }); - temp = getCord(xCord); - var temp2 = getCord(yCord); + tempX = getCord(xCord); + tempY = getCord(yCord); $.each(data,function(key,value) { - series[0].data.push({ name: value[dataLabel], x: temp[0][it], y: temp2[0][it], marker: {fillColor: colorCodes[it % 8]} , id: it } ); + series[0].data.push({ name: value[dataLabel], x: tempX[0][it], y: tempY[0][it], marker: {fillColor: colorCodes[it % 8]} , id: it } ); it++; }); currentSettings.xAxis.labels = { formatter : function() { - if(temp[1][this.value] && temp[1][this.value].length > 10) - return temp[1][this.value].substring(0,10); - else - return temp[1][this.value]; + 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(temp[1][this.value] && temp[1][this.value].length > 10) - return temp[1][this.value].substring(0,10); - else - return temp2[1][this.value]; + 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; From 7880782588e1609dac657a3c2b2f5a3630929859 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Mon, 1 Aug 2011 10:01:42 +0530 Subject: [PATCH 38/46] Added 'Max rows to plot' as input criteria --- tbl_zoom_select.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 6bc5d6016c..8955eecbc3 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -66,7 +66,6 @@ $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaTh $foreigners = PMA_getForeigners($db, $table); $flag = 1; $tbl_fields_type = $tbl_fields_collation = $tbl_fields_null = array(); - $maxPlotlLimit = $GLOBALS['cfg']['maxRowPlotLimit']; if(!isset($zoom_submit) && !isset($inputs)) $dataLabel = PMA_getDisplayField($db,$table); @@ -256,7 +255,7 @@ for($i = 0 ; $i < 4 ; $i++){ $dataLabel = PMA_getDisplayField($db,$table); } ?> -
+
+ + + + +
        
+ +
@@ -318,7 +327,7 @@ if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_ if ($w) { $sql_query .= ' WHERE ' . implode(' AND ', $w); } - $sql_query .= ' LIMIT ' . $maxPlotlLimit; + $sql_query .= ' LIMIT ' . $maxPlotLimit; /* * Query execution part From 241caff7818f69531400eecd1ea63849009bffa9 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Wed, 3 Aug 2011 09:17:16 +0530 Subject: [PATCH 39/46] Used AJAX to get data row on point select, hence reducing the amount of data to be sent from server initially for plot. --- js/tbl_zoom_plot.js | 54 +++++++++++++++++++++++++++++---------------- tbl_zoom_select.php | 27 ++++++++++++++++++++++- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 6060969ee6..9b67311ee7 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -58,7 +58,7 @@ function isEmpty(obj) { ** @param field: field type (as in database structure) **/ function getType(field) { - if(field.toString().search(/int/i) != -1 || field.toString().search(/decimal/i) != -1) + 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) return 'text'; @@ -181,17 +181,17 @@ $(document).ready(function() { //Prevent default submission of form event.preventDefault(); - //Update the data, find changed values + //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 data[currentData]) { + for (key in selectedRow) { if (key != 'where_clause'){ - var oldVal = data[currentData][key]; + var oldVal = selectedRow[key]; var newVal = ($('#fields_null_id_' + it).attr('checked')) ? null : $('#fieldID_' + it).val(); if (oldVal != newVal){ - data[currentData][key] = newVal; + selectedRow[key] = newVal; newValues[key] = newVal; if(key == xLabel) xChange = true; @@ -201,8 +201,8 @@ $(document).ready(function() { } it++ }//End data update - - //Update the chart series and replot + + //Update the chart series and replot if (xChange || yChange) { var newSeries = new Array(); newSeries[0] = new Object(); @@ -211,9 +211,9 @@ $(document).ready(function() { }; //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] = data[currentData][xLabel]; + xCord[currentData] = selectedRow[xLabel]; if(xType == 'numeric') { - currentChart.series[0].data[currentData].update({ x : data[currentData][xLabel] }); + currentChart.series[0].data[currentData].update({ x : selectedRow[xLabel] }); currentChart.xAxis[0].setExtremes(Array.min(xCord) - 2,Array.max(xCord) + 2); } else { @@ -244,9 +244,9 @@ $(document).ready(function() { } if(yChange) { - yCord[currentData] = data[currentData][yLabel]; + yCord[currentData] = selectedRow[yLabel]; if(yType == 'numeric') { - currentChart.series[0].data[currentData].update({ y : data[currentData][yLabel] }); + currentChart.series[0].data[currentData].update({ y : selectedRow[yLabel] }); currentChart.yAxis[0].setExtremes(Array.min(yCord) - 2,Array.max(yCord) + 2); } else { @@ -326,6 +326,7 @@ $(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(); @@ -362,15 +363,30 @@ $(document).ready(function() { events: { click: function() { var id = this.id; - var j = 4; - for( key in data[id]) { - if (data[id][key] == null) - $('#fields_null_id_' + j).attr('checked', true); - else - $('#fieldID_' + j).val(data[id][key]); - j++; - } + 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, + } + $.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; + }); + $("#dataDisplay").dialog("open"); }, } diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 8955eecbc3..4ce2001717 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -29,6 +29,23 @@ $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js'; $GLOBALS['js_include'][] = 'jquery/timepicker.js'; +/** + * Handle AJAX request for data row on point select + * @var post_params Object containing parameters for the POST request + */ + +if (isset($_REQUEST['get_data_row']) && $_REQUEST['get_data_row'] == true) { + + $extra_data = array(); + $row_info_query = 'SELECT * FROM `' . $_REQUEST['db'] . '`.`' . $_REQUEST['table'] . '` WHERE ' . $_REQUEST['where_clause']; + $result = PMA_DBI_query( $row_info_query . ";" , null, PMA_DBI_QUERY_STORE); + $fields_meta = PMA_DBI_get_fields_meta($result); + while ($row = PMA_DBI_fetch_assoc($result)) + $extra_data['row_info'] = $row; + + PMA_ajaxResponse(NULL, true, $extra_data); +} + $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage); /** * Not selection yet required -> displays the selection form @@ -71,6 +88,7 @@ $titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaTh ?> +
/> + +
@@ -343,7 +365,10 @@ if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_ $uniqueCondition = PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $tmpRow, true); //Append it to row array as where_clause $row['where_clause'] = $uniqueCondition[0]; - $data[] = $row; + if($dataLabel == $inputs[0] || $dataLabel == $inputs[1]) + $data[] = array($inputs[0] => $row[$inputs[0]], $inputs[1] => $row[$inputs[1]], 'where_clause' => $uniqueCondition[0]); + else + $data[] = array($inputs[0] => $row[$inputs[0]], $inputs[1] => $row[$inputs[1]], $dataLabel => $row[$dataLabel], 'where_clause' => $uniqueCondition[0]); } ?> From e3cb99d540a305caaa58f91d71a5f87d96f28e50 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 12 Aug 2011 01:39:22 +0530 Subject: [PATCH 40/46] Added better support for datetime fields --- js/date.js | 335 ++++++++++++++++++++++++++++++++++++++++++++ js/tbl_zoom_plot.js | 131 +++++++++++++---- tbl_zoom_select.php | 2 + 3 files changed, 444 insertions(+), 24 deletions(-) create mode 100644 js/date.js diff --git a/js/date.js b/js/date.js new file mode 100644 index 0000000000..9a923408ad --- /dev/null +++ b/js/date.js @@ -0,0 +1,335 @@ +// =================================================================== +// Author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + +// HISTORY +// ------------------------------------------------------------------ +// May 17, 2003: Fixed bug in parseDate() for dates <1970 +// March 11, 2003: Added parseDate() function +// March 11, 2003: Added "NNN" formatting option. Doesn't match up +// perfectly with SimpleDateFormat formats, but +// backwards-compatability was required. + +// ------------------------------------------------------------------ +// These functions use the same 'format' strings as the +// java.text.SimpleDateFormat class, with minor exceptions. +// The format string consists of the following abbreviations: +// +// Field | Full Form | Short Form +// -------------+--------------------+----------------------- +// Year | yyyy (4 digits) | yy (2 digits), y (2 or 4 digits) +// Month | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits) +// | NNN (abbr.) | +// Day of Month | dd (2 digits) | d (1 or 2 digits) +// Day of Week | EE (name) | E (abbr) +// Hour (1-12) | hh (2 digits) | h (1 or 2 digits) +// Hour (0-23) | HH (2 digits) | H (1 or 2 digits) +// Hour (0-11) | KK (2 digits) | K (1 or 2 digits) +// Hour (1-24) | kk (2 digits) | k (1 or 2 digits) +// Minute | mm (2 digits) | m (1 or 2 digits) +// Second | ss (2 digits) | s (1 or 2 digits) +// AM/PM | a | +// +// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm! +// Examples: +// "MMM d, y" matches: January 01, 2000 +// Dec 1, 1900 +// Nov 20, 00 +// "M/d/yy" matches: 01/20/00 +// 9/2/00 +// "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM" +// ------------------------------------------------------------------ + +var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); +var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat'); +function LZ(x) {return(x<0||x>9?"":"0")+x} + +// ------------------------------------------------------------------ +// isDate ( date_string, format_string ) +// Returns true if date string matches format of format string and +// is a valid date. Else returns false. +// It is recommended that you trim whitespace around the value before +// passing it to this function, as whitespace is NOT ignored! +// ------------------------------------------------------------------ +function isDate(val,format) { + var date=getDateFromFormat(val,format); + if (date==0) { return false; } + return true; + } + +// ------------------------------------------------------------------- +// compareDates(date1,date1format,date2,date2format) +// Compare two date strings to see which is greater. +// Returns: +// 1 if date1 is greater than date2 +// 0 if date2 is greater than date1 of if they are the same +// -1 if either of the dates is in an invalid format +// ------------------------------------------------------------------- +function compareDates(date1,dateformat1,date2,dateformat2) { + var d1=getDateFromFormat(date1,dateformat1); + var d2=getDateFromFormat(date2,dateformat2); + if (d1==0 || d2==0) { + return -1; + } + else if (d1 > d2) { + return 1; + } + return 0; + } + +// ------------------------------------------------------------------ +// formatDate (date_object, format) +// Returns a date in the output format specified. +// The format string uses the same abbreviations as in getDateFromFormat() +// ------------------------------------------------------------------ +function formatDate(date,format) { + format=format+""; + var result=""; + var i_format=0; + var c=""; + var token=""; + var y=date.getYear()+""; + var M=date.getMonth()+1; + var d=date.getDate(); + var E=date.getDay(); + var H=date.getHours(); + var m=date.getMinutes(); + var s=date.getSeconds(); + var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k; + // Convert real date parts into formatted versions + var value=new Object(); + if (y.length < 4) {y=""+(y-0+1900);} + value["y"]=""+y; + value["yyyy"]=y; + value["yy"]=y.substring(2,4); + value["M"]=M; + value["MM"]=LZ(M); + value["MMM"]=MONTH_NAMES[M-1]; + value["NNN"]=MONTH_NAMES[M+11]; + value["d"]=d; + value["dd"]=LZ(d); + value["E"]=DAY_NAMES[E+7]; + value["EE"]=DAY_NAMES[E]; + value["H"]=H; + value["HH"]=LZ(H); + if (H==0){value["h"]=12;} + else if (H>12){value["h"]=H-12;} + else {value["h"]=H;} + value["hh"]=LZ(value["h"]); + if (H>11){value["K"]=H-12;} else {value["K"]=H;} + value["k"]=H+1; + value["KK"]=LZ(value["K"]); + value["kk"]=LZ(value["k"]); + if (H > 11) { value["a"]="PM"; } + else { value["a"]="AM"; } + value["m"]=m; + value["mm"]=LZ(m); + value["s"]=s; + value["ss"]=LZ(s); + while (i_format < format.length) { + c=format.charAt(i_format); + token=""; + while ((format.charAt(i_format)==c) && (i_format < format.length)) { + token += format.charAt(i_format++); + } + if (value[token] != null) { result=result + value[token]; } + else { result=result + token; } + } + return result; + } + +// ------------------------------------------------------------------ +// Utility functions for parsing in getDateFromFormat() +// ------------------------------------------------------------------ +function _isInteger(val) { + var digits="1234567890"; + for (var i=0; i < val.length; i++) { + if (digits.indexOf(val.charAt(i))==-1) { return false; } + } + return true; + } +function _getInt(str,i,minlength,maxlength) { + for (var x=maxlength; x>=minlength; x--) { + var token=str.substring(i,i+x); + if (token.length < minlength) { return null; } + if (_isInteger(token)) { return token; } + } + return null; + } + +// ------------------------------------------------------------------ +// getDateFromFormat( date_string , format_string ) +// +// This function takes a date string and a format string. It matches +// If the date string matches the format string, it returns the +// getTime() of the date. If it does not match, it returns 0. +// ------------------------------------------------------------------ +function getDateFromFormat(val,format) { + val=val+""; + format=format+""; + var i_val=0; + var i_format=0; + var c=""; + var token=""; + var token2=""; + var x,y; + var now=new Date(); + var year=now.getYear(); + var month=now.getMonth()+1; + var date=1; + var hh=now.getHours(); + var mm=now.getMinutes(); + var ss=now.getSeconds(); + var ampm=""; + + while (i_format < format.length) { + // Get next token from format string + c=format.charAt(i_format); + token=""; + while ((format.charAt(i_format)==c) && (i_format < format.length)) { + token += format.charAt(i_format++); + } + // Extract contents of value based on format token + if (token=="yyyy" || token=="yy" || token=="y") { + if (token=="yyyy") { x=4;y=4; } + if (token=="yy") { x=2;y=2; } + if (token=="y") { x=2;y=4; } + year=_getInt(val,i_val,x,y); + if (year==null) { return 0; } + i_val += year.length; + if (year.length==2) { + if (year > 70) { year=1900+(year-0); } + else { year=2000+(year-0); } + } + } + else if (token=="MMM"||token=="NNN"){ + month=0; + for (var i=0; i11)) { + month=i+1; + if (month>12) { month -= 12; } + i_val += month_name.length; + break; + } + } + } + if ((month < 1)||(month>12)){return 0;} + } + else if (token=="EE"||token=="E"){ + for (var i=0; i12)){return 0;} + i_val+=month.length;} + else if (token=="dd"||token=="d") { + date=_getInt(val,i_val,token.length,2); + if(date==null||(date<1)||(date>31)){return 0;} + i_val+=date.length;} + else if (token=="hh"||token=="h") { + hh=_getInt(val,i_val,token.length,2); + if(hh==null||(hh<1)||(hh>12)){return 0;} + i_val+=hh.length;} + else if (token=="HH"||token=="H") { + hh=_getInt(val,i_val,token.length,2); + if(hh==null||(hh<0)||(hh>23)){return 0;} + i_val+=hh.length;} + else if (token=="KK"||token=="K") { + hh=_getInt(val,i_val,token.length,2); + if(hh==null||(hh<0)||(hh>11)){return 0;} + i_val+=hh.length;} + else if (token=="kk"||token=="k") { + hh=_getInt(val,i_val,token.length,2); + if(hh==null||(hh<1)||(hh>24)){return 0;} + i_val+=hh.length;hh--;} + else if (token=="mm"||token=="m") { + mm=_getInt(val,i_val,token.length,2); + if(mm==null||(mm<0)||(mm>59)){return 0;} + i_val+=mm.length;} + else if (token=="ss"||token=="s") { + ss=_getInt(val,i_val,token.length,2); + if(ss==null||(ss<0)||(ss>59)){return 0;} + i_val+=ss.length;} + else if (token=="a") { + if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";} + else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";} + else {return 0;} + i_val+=2;} + else { + if (val.substring(i_val,i_val+token.length)!=token) {return 0;} + else {i_val+=token.length;} + } + } + // If there are any trailing characters left in the value, it doesn't match + if (i_val != val.length) { return 0; } + // Is date valid for month? + if (month==2) { + // Check for leap year + if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year + if (date > 29){ return 0; } + } + else { if (date > 28) { return 0; } } + } + if ((month==4)||(month==6)||(month==9)||(month==11)) { + if (date > 30) { return 0; } + } + // Correct hours value + if (hh<12 && ampm=="PM") { hh=hh-0+12; } + else if (hh>11 && ampm=="AM") { hh-=12; } + var newdate=new Date(year,month-1,date,hh,mm,ss); + return newdate.getTime(); + } + +// ------------------------------------------------------------------ +// parseDate( date_string [, prefer_euro_format] ) +// +// This function takes a date string and tries to match it to a +// number of possible date formats to get the value. It will try to +// match against the following international formats, in this order: +// y-M-d MMM d, y MMM d,y y-MMM-d d-MMM-y MMM d +// M/d/y M-d-y M.d.y MMM-d M/d M-d +// d/M/y d-M-y d.M.y d-MMM d/M d-M +// A second argument may be passed to instruct the method to search +// for formats like d/M/y (european format) before M/d/y (American). +// Returns a Date object or null if no patterns match. +// ------------------------------------------------------------------ +function parseDate(val) { + var preferEuro=(arguments.length==2)?arguments[1]:false; + generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d'); + monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d'); + dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M'); + var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst'); + var d=null; + for (var i=0; i 10) return tempX[1][this.value].substring(0,10) @@ -459,21 +525,38 @@ $(document).ready(function() { return tempX[1][this.value]; } } + 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()); + }} + } xCord = tempX[2]; } - else if (xType =='numeric' && yType =='text') { + 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) { - series[0].data.push({ name: value[dataLabel], y: tempY[0][it], x: value[xLabel], marker: {fillColor: colorCodes[it % 8]} , id: it } ); + 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++; }); - currentSettings.xAxis.max = Array.max(xCord) + 3 - currentSettings.xAxis.min = Array.min(xCord) - 2 + 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()); + }} + } currentSettings.yAxis.labels = { formatter : function() { if(tempY[1][this.value] && tempY[1][this.value].length > 10) return tempY[1][this.value].substring(0,10) diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php index 4ce2001717..cdb784d00b 100644 --- a/tbl_zoom_select.php +++ b/tbl_zoom_select.php @@ -20,6 +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'][] = 'date.js'; $GLOBALS['js_include'][] = 'highcharts/highcharts.js'; /* Files required for chart exporting */ $GLOBALS['js_include'][] = 'highcharts/exporting.js'; @@ -363,6 +364,7 @@ if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_ $tmpRow[] = $val; //Get unique conditon on each row (will be needed for row update) $uniqueCondition = PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $tmpRow, true); + //Append it to row array as where_clause $row['where_clause'] = $uniqueCondition[0]; if($dataLabel == $inputs[0] || $dataLabel == $inputs[1]) From 201331275bff7e3e67e3d5f3fb2bc706e302ad27 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 12 Aug 2011 18:38:53 +0530 Subject: [PATCH 41/46] Fixed: yAxis min value determined on plot generation and not 0 by default --- js/tbl_zoom_plot.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index e94dfd7a67..49fbe66e97 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -447,6 +447,7 @@ $(document).ready(function() { title: { text: $('#tableid_0').val() }, }, yAxis: { + min: null, title: { text: $('#tableid_1').val() }, }, } From 557734c57f45e24abae08a031dde25dab73f1a05 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 12 Aug 2011 20:03:03 +0530 Subject: [PATCH 42/46] bug fix --- js/tbl_zoom_plot.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 49fbe66e97..3f6be1c55c 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -80,10 +80,10 @@ function getTimeStamp(val,type) { return getDateFromFormat(val,'yyyy-MM-dd HH:mm:ss', val) } else if(type.toString().search(/time/i) != -1) { - return Highcharts.dateFormat('HH:mm:ss', val) + return getDateFromFormat(val,'HH:mm:ss') } else if (type.toString().search(/date/i) != -1) { - return Highcharts.dateFormat('yyyy-mm-dd', val) + return getDateFromFormat(val,'yyyy-MM-dd') } } @@ -479,6 +479,7 @@ $(document).ready(function() { if (xType != 'text' && yType != 'text') { $.each(data,function(key,value) { var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val()); + alert(xVal); 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]); From 67dc02f23db70391220dc0336f2110645a34a9d2 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 12 Aug 2011 20:06:27 +0530 Subject: [PATCH 43/46] Fixed: false timestamp error --- js/tbl_zoom_plot.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index 3f6be1c55c..e82b145c4a 100644 --- a/js/tbl_zoom_plot.js +++ b/js/tbl_zoom_plot.js @@ -479,7 +479,6 @@ $(document).ready(function() { if (xType != 'text' && yType != 'text') { $.each(data,function(key,value) { var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val()); - alert(xVal); 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]); From ae5ef42beff0475de4a841ff18953e4f66880c40 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 12 Aug 2011 23:15:38 +0530 Subject: [PATCH 44/46] Fixed: Timestamp for time associated fields needed extra 19800000 (+5:30) value --- js/tbl_zoom_plot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js index e82b145c4a..b9c0d75364 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) + return Highcharts.dateFormat('%H:%M:%S', val + 19800000) } else if (type.toString().search(/date/i) != -1) { return Highcharts.dateFormat('%Y-%m-%e', val) @@ -80,7 +80,7 @@ function getTimeStamp(val,type) { return getDateFromFormat(val,'yyyy-MM-dd HH:mm:ss', val) } else if(type.toString().search(/time/i) != -1) { - return getDateFromFormat(val,'HH:mm:ss') + 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') From 1b7e2f6c7be6c7a96d780a7e9870d498f84e7339 Mon Sep 17 00:00:00 2001 From: Ammar Yasir Date: Fri, 12 Aug 2011 23:30:21 +0530 Subject: [PATCH 45/46] Added: Missing rgbcolor.js file --- js/canvg/rgbcolor.js | 288 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 js/canvg/rgbcolor.js diff --git a/js/canvg/rgbcolor.js b/js/canvg/rgbcolor.js new file mode 100644 index 0000000000..0338a1696d --- /dev/null +++ b/js/canvg/rgbcolor.js @@ -0,0 +1,288 @@ +/** + * A class to parse color values + * @author Stoyan Stefanov + * @link http://www.phpied.com/rgb-color-parser-in-javascript/ + * @license Use it if you like it + */ +function RGBColor(color_string) +{ + this.ok = false; + + // strip any leading # + if (color_string.charAt(0) == '#') { // remove # if any + color_string = color_string.substr(1,6); + } + + color_string = color_string.replace(/ /g,''); + color_string = color_string.toLowerCase(); + + // before getting into regexps, try simple matches + // and overwrite the input + var simple_colors = { + aliceblue: 'f0f8ff', + antiquewhite: 'faebd7', + aqua: '00ffff', + aquamarine: '7fffd4', + azure: 'f0ffff', + beige: 'f5f5dc', + bisque: 'ffe4c4', + black: '000000', + blanchedalmond: 'ffebcd', + blue: '0000ff', + blueviolet: '8a2be2', + brown: 'a52a2a', + burlywood: 'deb887', + cadetblue: '5f9ea0', + chartreuse: '7fff00', + chocolate: 'd2691e', + coral: 'ff7f50', + cornflowerblue: '6495ed', + cornsilk: 'fff8dc', + crimson: 'dc143c', + cyan: '00ffff', + darkblue: '00008b', + darkcyan: '008b8b', + darkgoldenrod: 'b8860b', + darkgray: 'a9a9a9', + darkgreen: '006400', + darkkhaki: 'bdb76b', + darkmagenta: '8b008b', + darkolivegreen: '556b2f', + darkorange: 'ff8c00', + darkorchid: '9932cc', + darkred: '8b0000', + darksalmon: 'e9967a', + darkseagreen: '8fbc8f', + darkslateblue: '483d8b', + darkslategray: '2f4f4f', + darkturquoise: '00ced1', + darkviolet: '9400d3', + deeppink: 'ff1493', + deepskyblue: '00bfff', + dimgray: '696969', + dodgerblue: '1e90ff', + feldspar: 'd19275', + firebrick: 'b22222', + floralwhite: 'fffaf0', + forestgreen: '228b22', + fuchsia: 'ff00ff', + gainsboro: 'dcdcdc', + ghostwhite: 'f8f8ff', + gold: 'ffd700', + goldenrod: 'daa520', + gray: '808080', + green: '008000', + greenyellow: 'adff2f', + honeydew: 'f0fff0', + hotpink: 'ff69b4', + indianred : 'cd5c5c', + indigo : '4b0082', + ivory: 'fffff0', + khaki: 'f0e68c', + lavender: 'e6e6fa', + lavenderblush: 'fff0f5', + lawngreen: '7cfc00', + lemonchiffon: 'fffacd', + lightblue: 'add8e6', + lightcoral: 'f08080', + lightcyan: 'e0ffff', + lightgoldenrodyellow: 'fafad2', + lightgrey: 'd3d3d3', + lightgreen: '90ee90', + lightpink: 'ffb6c1', + lightsalmon: 'ffa07a', + lightseagreen: '20b2aa', + lightskyblue: '87cefa', + lightslateblue: '8470ff', + lightslategray: '778899', + lightsteelblue: 'b0c4de', + lightyellow: 'ffffe0', + lime: '00ff00', + limegreen: '32cd32', + linen: 'faf0e6', + magenta: 'ff00ff', + maroon: '800000', + mediumaquamarine: '66cdaa', + mediumblue: '0000cd', + mediumorchid: 'ba55d3', + mediumpurple: '9370d8', + mediumseagreen: '3cb371', + mediumslateblue: '7b68ee', + mediumspringgreen: '00fa9a', + mediumturquoise: '48d1cc', + mediumvioletred: 'c71585', + midnightblue: '191970', + mintcream: 'f5fffa', + mistyrose: 'ffe4e1', + moccasin: 'ffe4b5', + navajowhite: 'ffdead', + navy: '000080', + oldlace: 'fdf5e6', + olive: '808000', + olivedrab: '6b8e23', + orange: 'ffa500', + orangered: 'ff4500', + orchid: 'da70d6', + palegoldenrod: 'eee8aa', + palegreen: '98fb98', + paleturquoise: 'afeeee', + palevioletred: 'd87093', + papayawhip: 'ffefd5', + peachpuff: 'ffdab9', + peru: 'cd853f', + pink: 'ffc0cb', + plum: 'dda0dd', + powderblue: 'b0e0e6', + purple: '800080', + red: 'ff0000', + rosybrown: 'bc8f8f', + royalblue: '4169e1', + saddlebrown: '8b4513', + salmon: 'fa8072', + sandybrown: 'f4a460', + seagreen: '2e8b57', + seashell: 'fff5ee', + sienna: 'a0522d', + silver: 'c0c0c0', + skyblue: '87ceeb', + slateblue: '6a5acd', + slategray: '708090', + snow: 'fffafa', + springgreen: '00ff7f', + steelblue: '4682b4', + tan: 'd2b48c', + teal: '008080', + thistle: 'd8bfd8', + tomato: 'ff6347', + turquoise: '40e0d0', + violet: 'ee82ee', + violetred: 'd02090', + wheat: 'f5deb3', + white: 'ffffff', + whitesmoke: 'f5f5f5', + yellow: 'ffff00', + yellowgreen: '9acd32' + }; + for (var key in simple_colors) { + if (color_string == key) { + color_string = simple_colors[key]; + } + } + // emd of simple type-in colors + + // array of color definition objects + var color_defs = [ + { + re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, + example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'], + process: function (bits){ + return [ + parseInt(bits[1]), + parseInt(bits[2]), + parseInt(bits[3]) + ]; + } + }, + { + re: /^(\w{2})(\w{2})(\w{2})$/, + example: ['#00ff00', '336699'], + process: function (bits){ + return [ + parseInt(bits[1], 16), + parseInt(bits[2], 16), + parseInt(bits[3], 16) + ]; + } + }, + { + re: /^(\w{1})(\w{1})(\w{1})$/, + example: ['#fb0', 'f0f'], + process: function (bits){ + return [ + parseInt(bits[1] + bits[1], 16), + parseInt(bits[2] + bits[2], 16), + parseInt(bits[3] + bits[3], 16) + ]; + } + } + ]; + + // search through the definitions to find a match + for (var i = 0; i < color_defs.length; i++) { + var re = color_defs[i].re; + var processor = color_defs[i].process; + var bits = re.exec(color_string); + if (bits) { + channels = processor(bits); + this.r = channels[0]; + this.g = channels[1]; + this.b = channels[2]; + this.ok = true; + } + + } + + // validate/cleanup values + this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r); + this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g); + this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b); + + // some getters + this.toRGB = function () { + return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')'; + } + this.toHex = function () { + var r = this.r.toString(16); + var g = this.g.toString(16); + var b = this.b.toString(16); + if (r.length == 1) r = '0' + r; + if (g.length == 1) g = '0' + g; + if (b.length == 1) b = '0' + b; + return '#' + r + g + b; + } + + // help + this.getHelpXML = function () { + + var examples = new Array(); + // add regexps + for (var i = 0; i < color_defs.length; i++) { + var example = color_defs[i].example; + for (var j = 0; j < example.length; j++) { + examples[examples.length] = example[j]; + } + } + // add type-in colors + for (var sc in simple_colors) { + examples[examples.length] = sc; + } + + var xml = document.createElement('ul'); + xml.setAttribute('id', 'rgbcolor-examples'); + for (var i = 0; i < examples.length; i++) { + try { + var list_item = document.createElement('li'); + var list_color = new RGBColor(examples[i]); + var example_div = document.createElement('div'); + example_div.style.cssText = + 'margin: 3px; ' + + 'border: 1px solid black; ' + + 'background:' + list_color.toHex() + '; ' + + 'color:' + list_color.toHex() + ; + example_div.appendChild(document.createTextNode('test')); + var list_item_value = document.createTextNode( + ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex() + ); + list_item.appendChild(example_div); + list_item.appendChild(list_item_value); + xml.appendChild(list_item); + + } catch(e){} + } + return xml; + + } + +} + From 9147f30dc6b00dc63c998f1d2d3972d1a47e6c57 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Fri, 12 Aug 2011 14:44:55 -0400 Subject: [PATCH 46/46] Zoom-search in table Search --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 633d481373..e6c1bc4605 100644 --- a/ChangeLog +++ b/ChangeLog @@ -43,6 +43,7 @@ phpMyAdmin - ChangeLog + AJAX for table Operations copy table - bug #3380946 [export] no uid Query result export (Suhosin limit) + Grid editing in browse mode (replaces row inline edit) ++ Zoom-search in table Search 3.4.5.0 (not yet released) - bug #3375325 [interface] Page list in navigation frame looks odd