diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-01-09 10:55:03 +0100 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-01-09 13:09:38 +0100 |
| commit | 04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa (patch) | |
| tree | 5c691241355c943a3c68ddb06b8cf8c60aa11319 /srcs/phpmyadmin/js/table/zoom_plot_jqplot.js | |
| parent | 7e0d85db834d6351ed85d01e5126ac31dc510b86 (diff) | |
| download | ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.gz ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.bz2 ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.zip | |
phpmyadmin working
Diffstat (limited to 'srcs/phpmyadmin/js/table/zoom_plot_jqplot.js')
| -rw-r--r-- | srcs/phpmyadmin/js/table/zoom_plot_jqplot.js | 607 |
1 files changed, 607 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/js/table/zoom_plot_jqplot.js b/srcs/phpmyadmin/js/table/zoom_plot_jqplot.js new file mode 100644 index 0000000..659e6a7 --- /dev/null +++ b/srcs/phpmyadmin/js/table/zoom_plot_jqplot.js @@ -0,0 +1,607 @@ +// TODO: change the axis +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + ** @fileoverview JavaScript functions used on tbl_select.php + ** + ** @requires jQuery + ** @requires js/functions.js + **/ + + +/** + ** Display Help/Info + **/ +function displayHelp () { + $('<div></div>') + .append(Messages.strDisplayHelp) + .appendTo('#page_content') + .dialog({ + width: 450, + height: 'auto', + title: Messages.strHelpTitle + }); + return false; +} + +/** + ** 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); +}; + +/** + ** Checks if a string contains only numeric value + ** @param n: String (to be checked) + **/ +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; +} + +/** + ** Converts a date/time into timestamp + ** @param val String Date + ** @param type Sring Field type(datetime/timestamp/time/date) + **/ +function getTimeStamp (val, type) { + if (type.toString().search(/datetime/i) !== -1 || + type.toString().search(/timestamp/i) !== -1 + ) { + return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', val); + } else if (type.toString().search(/time/i) !== -1) { + return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', '1970-01-01 ' + val); + } else if (type.toString().search(/date/i) !== -1) { + return $.datepicker.parseDate('yy-mm-dd', val); + } +} + +/** + ** Classifies the field type into numeric,timeseries or text + ** @param field: field type (as in database structure) + **/ +function getType (field) { + if (field.toString().search(/int/i) !== -1 || + field.toString().search(/decimal/i) !== -1 || + field.toString().search(/year/i) !== -1 + ) { + return 'numeric'; + } else if (field.toString().search(/time/i) !== -1 || + field.toString().search(/date/i) !== -1 + ) { + return 'time'; + } else { + return 'text'; + } +} + +/** + * Unbind all event handlers before tearing down a page + */ +AJAX.registerTeardown('table/zoom_plot_jqplot.js', function () { + $('#tableid_0').off('change'); + $('#tableid_1').off('change'); + $('#tableid_2').off('change'); + $('#tableid_3').off('change'); + $('#inputFormSubmitId').off('click'); + $('#togglesearchformlink').off('click'); + $(document).off('keydown', '#dataDisplay :input'); + $('button.button-reset').off('click'); + $('div#resizer').off('resizestop'); + $('div#querychart').off('jqplotDataClick'); +}); + +AJAX.registerOnload('table/zoom_plot_jqplot.js', function () { + var currentChart = null; + var searchedDataKey = null; + var xLabel = $('#tableid_0').val(); + var yLabel = $('#tableid_1').val(); + // will be updated via Ajax + var xType = $('#types_0').val(); + var yType = $('#types_1').val(); + var dataLabel = $('#dataLabel').val(); + + // Get query result + var searchedData; + try { + searchedData = JSON.parse($('#querydata').html()); + } catch (err) { + searchedData = null; + } + + /** + ** Input form submit on field change + **/ + + // first column choice corresponds to the X axis + $('#tableid_0').on('change', function () { + // AJAX request for field type, collation, operators, and value field + $.post('tbl_zoom_select.php', { + 'ajax_request' : true, + 'change_tbl_info' : true, + 'server' : CommonParams.get('server'), + 'db' : CommonParams.get('db'), + 'table' : CommonParams.get('table'), + 'field' : $('#tableid_0').val(), + 'it' : 0 + }, function (data) { + $('#tableFieldsId').find('tr:eq(1) td:eq(0)').html(data.field_type); + $('#tableFieldsId').find('tr:eq(1) td:eq(1)').html(data.field_collation); + $('#tableFieldsId').find('tr:eq(1) td:eq(2)').html(data.field_operators); + $('#tableFieldsId').find('tr:eq(1) td:eq(3)').html(data.field_value); + xLabel = $('#tableid_0').val(); + $('#types_0').val(data.field_type); + xType = data.field_type; + $('#collations_0').val(data.field_collations); + Functions.addDateTimePicker(); + }); + }); + + // second column choice corresponds to the Y axis + $('#tableid_1').on('change', function () { + // AJAX request for field type, collation, operators, and value field + $.post('tbl_zoom_select.php', { + 'ajax_request' : true, + 'change_tbl_info' : true, + 'server' : CommonParams.get('server'), + 'db' : CommonParams.get('db'), + 'table' : CommonParams.get('table'), + 'field' : $('#tableid_1').val(), + 'it' : 1 + }, function (data) { + $('#tableFieldsId').find('tr:eq(2) td:eq(0)').html(data.field_type); + $('#tableFieldsId').find('tr:eq(2) td:eq(1)').html(data.field_collation); + $('#tableFieldsId').find('tr:eq(2) td:eq(2)').html(data.field_operators); + $('#tableFieldsId').find('tr:eq(2) td:eq(3)').html(data.field_value); + yLabel = $('#tableid_1').val(); + $('#types_1').val(data.field_type); + yType = data.field_type; + $('#collations_1').val(data.field_collations); + Functions.addDateTimePicker(); + }); + }); + + $('#tableid_2').on('change', function () { + // AJAX request for field type, collation, operators, and value field + $.post('tbl_zoom_select.php', { + 'ajax_request' : true, + 'change_tbl_info' : true, + 'server' : CommonParams.get('server'), + 'db' : CommonParams.get('db'), + 'table' : CommonParams.get('table'), + 'field' : $('#tableid_2').val(), + 'it' : 2 + }, function (data) { + $('#tableFieldsId').find('tr:eq(4) td:eq(0)').html(data.field_type); + $('#tableFieldsId').find('tr:eq(4) td:eq(1)').html(data.field_collation); + $('#tableFieldsId').find('tr:eq(4) td:eq(2)').html(data.field_operators); + $('#tableFieldsId').find('tr:eq(4) td:eq(3)').html(data.field_value); + $('#types_2').val(data.field_type); + $('#collations_2').val(data.field_collations); + Functions.addDateTimePicker(); + }); + }); + + $('#tableid_3').on('change', function () { + // AJAX request for field type, collation, operators, and value field + $.post('tbl_zoom_select.php', { + 'ajax_request' : true, + 'change_tbl_info' : true, + 'server' : CommonParams.get('server'), + 'db' : CommonParams.get('db'), + 'table' : CommonParams.get('table'), + 'field' : $('#tableid_3').val(), + 'it' : 3 + }, function (data) { + $('#tableFieldsId').find('tr:eq(5) td:eq(0)').html(data.field_type); + $('#tableFieldsId').find('tr:eq(5) td:eq(1)').html(data.field_collation); + $('#tableFieldsId').find('tr:eq(5) td:eq(2)').html(data.field_operators); + $('#tableFieldsId').find('tr:eq(5) td:eq(3)').html(data.field_value); + $('#types_3').val(data.field_type); + $('#collations_3').val(data.field_collations); + Functions.addDateTimePicker(); + }); + }); + + /** + * Input form validation + **/ + $('#inputFormSubmitId').on('click', function () { + if ($('#tableid_0').get(0).selectedIndex === 0 || $('#tableid_1').get(0).selectedIndex === 0) { + Functions.ajaxShowMessage(Messages.strInputNull); + } else if (xLabel === yLabel) { + Functions.ajaxShowMessage(Messages.strSameInputs); + } + }); + + /** + ** Prepare a div containing a link, otherwise it's incorrectly displayed + ** after a couple of clicks + **/ + $('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>') + .insertAfter('#zoom_search_form') + // don't show it until we have results on-screen + .hide(); + + $('#togglesearchformlink') + .html(Messages.strShowSearchCriteria) + .on('click', function () { + var $link = $(this); + $('#zoom_search_form').slideToggle(); + if ($link.text() === Messages.strHideSearchCriteria) { + $link.text(Messages.strShowSearchCriteria); + } else { + $link.text(Messages.strHideSearchCriteria); + } + // avoid default click action + return false; + }); + + /** + ** Set dialog properties for the data display form + **/ + var buttonOptions = {}; + /* + * Handle saving of a row in the editor + */ + buttonOptions[Messages.strSave] = function () { + // Find changed values by comparing form values with selectedRow Object + var newValues = {};// Stores the values changed from original + var sqlTypes = {}; + var it = 0; + var xChange = false; + var yChange = false; + var key; + var tempGetVal = function () { + return $(this).val(); + }; + for (key in selectedRow) { + var oldVal = selectedRow[key]; + var newVal = ($('#edit_fields_null_id_' + it).prop('checked')) ? null : $('#edit_fieldID_' + it).val(); + if (newVal instanceof Array) { // when the column is of type SET + newVal = $('#edit_fieldID_' + it).map(tempGetVal).get().join(','); + } + if (oldVal !== newVal) { + selectedRow[key] = newVal; + newValues[key] = newVal; + if (key === xLabel) { + xChange = true; + searchedData[searchedDataKey][xLabel] = newVal; + } else if (key === yLabel) { + yChange = true; + searchedData[searchedDataKey][yLabel] = newVal; + } + } + var $input = $('#edit_fieldID_' + it); + if ($input.hasClass('bit')) { + sqlTypes[key] = 'bit'; + } else { + sqlTypes[key] = null; + } + it++; + } // End data update + + // Update the chart series and replot + if (xChange || yChange) { + // 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[searchedDataKey] = selectedRow[xLabel]; + // [searchedDataKey][0] contains the x value + if (xType === 'numeric') { + series[0][searchedDataKey][0] = selectedRow[xLabel]; + } else if (xType === 'time') { + series[0][searchedDataKey][0] = + getTimeStamp(selectedRow[xLabel], $('#types_0').val()); + } else { + series[0][searchedDataKey][0] = ''; + // TODO: text values + } + currentChart.series[0].data = series[0]; + // TODO: axis changing + currentChart.replot(); + } + if (yChange) { + yCord[searchedDataKey] = selectedRow[yLabel]; + // [searchedDataKey][1] contains the y value + if (yType === 'numeric') { + series[0][searchedDataKey][1] = selectedRow[yLabel]; + } else if (yType === 'time') { + series[0][searchedDataKey][1] = + getTimeStamp(selectedRow[yLabel], $('#types_1').val()); + } else { + series[0][searchedDataKey][1] = ''; + // TODO: text values + } + currentChart.series[0].data = series[0]; + // TODO: axis changing + currentChart.replot(); + } + } // End plot update + + // Generate SQL query for update + if (!isEmpty(newValues)) { + var sqlQuery = 'UPDATE `' + CommonParams.get('table') + '` SET '; + for (key in newValues) { + sqlQuery += '`' + key + '`='; + var value = newValues[key]; + + // null + if (value === null) { + sqlQuery += 'NULL, '; + + // empty + } else if ($.trim(value) === '') { + sqlQuery += '\'\', '; + + // other + } else { + // type explicitly identified + if (sqlTypes[key] !== null) { + if (sqlTypes[key] === 'bit') { + sqlQuery += 'b\'' + value + '\', '; + } + // type not explicitly identified + } else { + if (!isNumeric(value)) { + sqlQuery += '\'' + value + '\', '; + } else { + sqlQuery += value + ', '; + } + } + } + } + // remove two extraneous characters ', ' + sqlQuery = sqlQuery.substring(0, sqlQuery.length - 2); + sqlQuery += ' WHERE ' + Sql.urlDecode(searchedData[searchedDataKey].where_clause); + + // Post SQL query to sql.php + $.post('sql.php', { + 'server' : CommonParams.get('server'), + 'db' : CommonParams.get('db'), + 'ajax_request' : true, + 'sql_query' : sqlQuery, + 'inline_edit' : false + }, function (data) { + if (typeof data !== 'undefined' && data.success === true) { + $('#sqlqueryresultsouter').html(data.sql_query); + Functions.highlightSql($('#sqlqueryresultsouter')); + } else { + Functions.ajaxShowMessage(data.error, false); + } + }); // End $.post + }// End database update + $('#dataDisplay').dialog('close'); + }; + buttonOptions[Messages.strCancel] = function () { + $(this).dialog('close'); + }; + $('#dataDisplay').dialog({ + autoOpen: false, + title: Messages.strDataPointContent, + modal: true, + buttons: buttonOptions, + width: $('#dataDisplay').width() + 80, + open: function () { + $(this).find('input[type=checkbox]').css('margin', '0.5em'); + } + }); + /** + * Attach Ajax event handlers for input fields + * in the dialog. Used to submit the Ajax + * request when the ENTER key is pressed. + */ + $(document).on('keydown', '#dataDisplay :input', function (e) { + if (e.which === 13) { // 13 is the ENTER key + e.preventDefault(); + if (typeof buttonOptions[Messages.strSave] === 'function') { + buttonOptions[Messages.strSave].call(); + } + } + }); + + + /* + * Generate plot using jqplot + */ + + if (searchedData !== null) { + $('#zoom_search_form') + .slideToggle() + .hide(); + $('#togglesearchformlink') + .text(Messages.strShowSearchCriteria); + $('#togglesearchformdiv').show(); + var selectedRow; + var series = []; + var xCord = []; + var yCord = []; + var xVal; + var yVal; + var format; + + var options = { + series: [ + // for a scatter plot + { showLine: false } + ], + grid: { + drawBorder: false, + shadow: false, + background: 'rgba(0,0,0,0)' + }, + axes: { + xaxis: { + label: $('#tableid_0').val(), + labelRenderer: $.jqplot.CanvasAxisLabelRenderer + }, + yaxis: { + label: $('#tableid_1').val(), + labelRenderer: $.jqplot.CanvasAxisLabelRenderer + } + }, + highlighter: { + show: true, + tooltipAxes: 'y', + yvalues: 2, + // hide the first y value + formatString: '<span class="hide">%s</span>%s' + }, + cursor: { + show: true, + zoom: true, + showTooltip: false + } + }; + + // If data label is not set, do not show tooltips + if (dataLabel === '') { + options.highlighter.show = false; + } + + // Classify types as either numeric,time,text + xType = getType(xType); + yType = getType(yType); + + // could have multiple series but we'll have just one + series[0] = []; + + if (xType === 'time') { + var originalXType = $('#types_0').val(); + if (originalXType === 'date') { + format = '%Y-%m-%d'; + } + // TODO: does not seem to work + // else if (originalXType === 'time') { + // format = '%H:%M'; + // } else { + // format = '%Y-%m-%d %H:%M'; + // } + $.extend(options.axes.xaxis, { + renderer: $.jqplot.DateAxisRenderer, + tickOptions: { + formatString: format + } + }); + } + if (yType === 'time') { + var originalYType = $('#types_1').val(); + if (originalYType === 'date') { + format = '%Y-%m-%d'; + } + $.extend(options.axes.yaxis, { + renderer: $.jqplot.DateAxisRenderer, + tickOptions: { + formatString: format + } + }); + } + + $.each(searchedData, function (key, value) { + if (xType === 'numeric') { + xVal = parseFloat(value[xLabel]); + } + if (xType === 'time') { + xVal = getTimeStamp(value[xLabel], originalXType); + } + if (yType === 'numeric') { + yVal = parseFloat(value[yLabel]); + } + if (yType === 'time') { + yVal = getTimeStamp(value[yLabel], originalYType); + } + series[0].push([ + xVal, + yVal, + // extra Y values + value[dataLabel], // for highlighter + // (may set an undefined value) + value.where_clause, // for click on point + key // key from searchedData + ]); + }); + + // under IE 8, the initial display is mangled; after a manual + // resizing, it's ok + // under IE 9, everything is fine + currentChart = $.jqplot('querychart', series, options); + currentChart.resetZoom(); + + $('button.button-reset').on('click', function (event) { + event.preventDefault(); + currentChart.resetZoom(); + }); + + $('div#resizer').resizable(); + $('div#resizer').on('resizestop', function () { + // make room so that the handle will still appear + $('div#querychart').height($('div#resizer').height() * 0.96); + $('div#querychart').width($('div#resizer').width() * 0.96); + currentChart.replot({ resetAxes: true }); + }); + + $('div#querychart').on('jqplotDataClick', + function (event, seriesIndex, pointIndex, data) { + searchedDataKey = data[4]; // key from searchedData (global) + var fieldId = 0; + var postParams = { + 'ajax_request' : true, + 'get_data_row' : true, + 'server' : CommonParams.get('server'), + 'db' : CommonParams.get('db'), + 'table' : CommonParams.get('table'), + 'where_clause' : data[3] + }; + + $.post('tbl_zoom_select.php', postParams, function (data) { + // Row is contained in data.row_info, + // now fill the displayResultForm with row values + var key; + for (key in data.row_info) { + var $field = $('#edit_fieldID_' + fieldId); + var $fieldNull = $('#edit_fields_null_id_' + fieldId); + if (data.row_info[key] === null) { + $fieldNull.prop('checked', true); + $field.val(''); + } else { + $fieldNull.prop('checked', false); + if ($field.attr('multiple')) { // when the column is of type SET + $field.val(data.row_info[key].split(',')); + } else { + $field.val(data.row_info[key]); + } + } + fieldId++; + } + selectedRow = data.row_info; + }); + + $('#dataDisplay').dialog('open'); + } + ); + } + + $('#help_dialog').on('click', function () { + displayHelp(); + }); +}); |
