How to update data table on data change highcharts - javascript

I have a pie chart that I'm updating dynamically on button click using the code below.
On Button click
$("#myChart").highcharts().series[0].setData($.extend(true, [], data1))
I'm using keys to populate the data table.
keys: ['Count','Value'],
This works fine and updates the chart but I also have export data table enabled in export menu but that data table doesn't update. It remains the same on all successive button clicks.
How can I update the data table with button click to show data for new data.
here is a fiddle but it doesn't really use buttons but just to give you an idea of my chart : https://jsfiddle.net/mewohraz/1/
Update: The solution below works but I had to comment out this piece of code that I'm using to toggle the viewData table. It allows me to close the table if you click on viewData again. How do I get to work it with chart.viewData()?
Highcharts.Chart.prototype.viewData = function () {
if (!this.insertedTable) {
var div = document.createElement('div');
div.className = 'highcharts-data-table';
// Insert after the chart container
this.renderTo.parentNode.insertBefore(div, this.renderTo.nextSibling);
div.innerHTML = this.getTable();
this.insertedTable = true;
div.id = this.container.id + '-data-table';
}
else {
$('#' + this.container.id + '-data-table').toggle();
}
};

You need to call viewData internal method to refresh the data table:
$('#update').on('click', function() {
var data1 = [...];
chart.series[0].setData(data1);
chart.viewData();
});
Live demo: https://jsfiddle.net/BlackLabel/ahowu9tm/

Related

How to get the page of an item of Kendo Grid using ServerOperation

I'm trying to retrieve the page index of a selected object of the grid that is using ServerOperation, but I don't know how would I do that without too much complication.
Currently, I'm receiving an Id from the URL (https://...?ObjectId=12) and I will select this item in the grid, but first I have to show the page it is, so I'm trying to get the page number of this row.
The problem is that I'm using ServerOperation(true). In addition, I'm retrieving the paged list without any filters.
function _displayDetailsModal(id, selectRow = true, focusSelected = true) {
$(document).ready(() => {
var url = `${urls.Details}/${id}`;
if (selectRow) {
// GET PAGE OF ITEM THEN
// CHANGE TO PAGE THEN
kendoGrid.selectById(id);
}
if (focusSelected) {
kendoGrid.focusSelected(); // Scrolls to selected row.
}
loadModal(url);
});
}
Is this the kind of thing you are after?
Dojo: https://dojo.telerik.com/iNEViDIm/2
I have provided a simple input field where you can set the page number and then a button which will change the page to the selected page for you.
All I am doing is setting the datasource's page via the page method and then it will go off and make a read to the remote datasource for you and then return that page of data.
$('#btnPage').on('click',function(e){
var page = $('#pageNumber').val();
$('#pageLabel').html('Page Selected Is: ' + page);
var ds = $('#grid').data('kendoGrid').dataSource;
ds.page(parseInt(page));
});
If you select a page higher than the last available then it will just show the last page.
More info can be seen here: https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/page
If you need any further info let me know:
I ended up doing it on the server. That is how I did it:
Controller.cs
Instead of sending just the usual ToDataSourceResult, I add two fiels (PageIndex and ObjectId), and send it to the front-end to change the page and select the row.
[HttpPost("List")]
public IActionResult List([DataSourceRequest] DataSourceRequest request, RequestActionViewModel requestAction)
{
// Getting the pageIndex of the ObjectId present in requestAction.
var objectIndex = elementList.FindIndex(el => el.Id == requestAction.ObjectId) + 1;
var objectPageIndex = Math.Ceiling((decimal)objectIndex / request.PageSize);
var dataSourceResult = elementList.ToDataSourceResult(request);
return Json(new {
Data = dataSourceResult.Data,
Total = dataSourceResult.Total,
AggregateResults = dataSourceResult.AggregateResults,
Errors = dataSourceResult.Errors,
// Extra fields
PageIndex = objectPageIndex,
ObjectId = requestAction.ObjectId
});
}
index.js
I Get from the server the page and the id of the element, select the change the page of the grid, and select the element.
function onGridRequestEnd(e) {
this.unbind("requestEnd", onGridRequestEnd);
if (e.PageIndex) {
kendoGrid.bind("dataBound", function temp() {
// Custom method.
kendoGrid.selectById(e.ObjectId, e.PageIndex);
// To avoid looping.
kendoGrid.unbind("dataBound", temp);
});
}
}

Duplicate HTML in jQuery into a BootStrap Modal

The function below is called after an icon is clicked, which creates a modal. During the function, I traverse up the DOM, grab a HTML canvas and display it in the modal. The problem I am having is that it is removing the HTML I grab initially, I want it to be duplicated. Can anyone shed some light on this?
JS:
$('#chartModal').on('show.bs.modal', function (event) {
console.log('yeppp');
// Button that triggered the modal
const button = $(event.relatedTarget)
// Get corresponding chart's HTML
const chart = button.parent().next()[0]
var modal = $(this)
// Update modal's content with the corresponding chart
modal.find('.modal-body').html(chart)
})
Regards,
James.
Since you are using jQuery, you can use the .clone() method like so:
$('#chartModal').on('show.bs.modal', function (event) {
// Button that triggered the modal
var button = $(event.relatedTarget);
// Get corresponding chart's HTML
// "chart" is a plain node here
var chart = button.parent().next()[0];
var modal = $(this);
// Update modal's content with the corresponding chart
modal.find('.modal-body').html($(chart).clone());
})
// OR
$('#chartModal').on('show.bs.modal', function (event) {
// Button that triggered the modal
var button = $(event.relatedTarget);
// Get corresponding chart's HTML
// "chart" is now a jQuery object
var chart = button.parent().next();
var modal = $(this);
// Update modal's content with the corresponding chart
modal.find('.modal-body').html(chart.clone());
})
Your current code snippet seems overly complicated in my opinion.
Here's a different solution that might be easier to follow:
HTML:
...
<canvas class="one-of-my-charts"></canvas>
...
JS:
$('.one-of-my-charts').click(function(e) {
$('#the-chart-modal').html(e.target);
$('#the-chart-modal').modal('show');
});

DataTable does not re-draw after updating rows

I'm using the DataTables library to create a table with extra functionality. What I'd like to achieve, is that the user can select rows and then press a button. This will call the server, do some stuff and the rows should be updated accordingly.
However, after I'm done iterating over the rows to be changed and setting its values, re-drawing the table does not actually update its values. I update the data object, invalidate the cache and call table.draw(). It's very similar to the last example on this page.
I have created a JSFiddle of this issue. The button updates the date objects of the selected rows and the table is re-drawn, but the data inside the table is not updated. The core JS code:
$('#updateRow').click(function() {
//Get the table
var table = $('#example').DataTable();
//Iterate over selected rows
var rowData = table.rows({
selected: true
}).every(function() {
//For every selected row, update startDate
var d = this.data();
d.startDate = "01/01/2017";
console.log('Set startDate of ' + d.name + ' to ' + d.startDate);
//Invalidate the cache
this.invalidate();
});
//Re-draw the table
table.draw();
});
I forked and did the solution from your JsFiddle. Here's the relevant snippet from fiddle https://jsfiddle.net/k38r9be5/1/
var rowData = table.rows({
selected: true
}).every(function(rowIdx) {
var colIdx = 4; // startDate is the fifth column, or "4" from 0-base (0,1,2,3,4...)
table.cell( rowIdx, colIdx).data('01/01/2017').draw();
});
Basically, via the API you can get the cell object itself, and modify the contents with .data(). In your version you weren't actually getting a particular cell object and instead just copied the data contents of the row to a variable, and modified that.

How to get value from dropdown in datatables cell

I've got two datatables and there is a dropdown created in the second one with data from the first. I've created a jsbin here
If you add a couple of instructions to the first table (add any text and then click Add Instruction) - then click on the Load Copied Data button, you will see the dropdown box is populated from the first table.
If I do:
$('#btnTest').on('click', function (e) {
var tsor = $('#tblSORSInstall').dataTable();
var ins = tsor.fnGetData();
alert(ins);
});
It basically gives me the html for the dropdown - how do I get which value they have chosen? I was thinking of having a hidden column and updating that on the onchange of the dropdown, but is there a better way?
Thanks in advance
You may use jQuery.map() to generate an array of selected text/value, like below.
$('#btnTest').on('click', function (e) {
//var tsor = $('#tblSORSInstall').dataTable();
var ins = $('#tblSORSInstall').find("tbody select").map(function() {
return $(this).find(":selected").text() // get selected text
//return $(this).val() // get selected value
}).get()
alert ( JSON.stringify(ins, null, 2) )
});
Here is your JS Bin - updated
Using tsor.fnGetNodes() you can get all table row nodes, then you can loop through those and get the select values.
Final code will look something like
$('#btnTest').on('click', function (e) {
var tsor = $('#tblSORSInstall').dataTable();
var ins = tsor.fnGetData();
var a = tsor.fnGetNodes();
$.each(tsor.fnGetNodes(), function (index, value) {
alert($(value).find('select').val());
});
});

reload d3 graph when a 'dropdown menu value changes

I am trying to get my d3.js line chart reloading when the user chooses an item in a dropdown menu, with the data corresponding to this item.
My menu is a list of stock market values:
YHOO
FB
...
For each of these, I have a JSON file with the data.
The graph in itself is working.
I put the code in a [JSFiddle], which doesn't work because it is supposed to use d3 and knockout.js.
It may be easier to work from this Github Gist.
Anyway, the code past line 83 changes newValue for each choice in the dropdown.
The data is stored in yahoo.json and fb.json.
How can I have the graph reloading each time the user selects a new choice in the dropdown menu with the data associated with this choice?
Thank you SO MUCH.
EDIT: temporary hack
/*User's stock choice*/
var viewModel = {
choice: ["AAPL", "YHOO", "FB", "MSFT"],
selectedChoice: ko.observable("two"), /*Knockout.js is used for having an observable array*/
};
viewModel.selectedChoice.subscribe(function(newValue) {
console.log(newValue);
if (newValue === "YHOO") {
d3.select("svg").remove();
d3.json('yahoo.json', draw);
} else if (newValue === "FB") {
d3.select("svg").remove();
d3.json('fb.json', draw);
}
});
ko.applyBindings(viewModel);
You can actually use d3 to bind events to the dropdown menu and then call a function when an on change event occurs. The function would go off and, in your case, grab the stock values from Yahoo. The only real trick is getting the data out of this. I ended up console logging this and digging through until I found __data__. Using d3 means you don't need knockout for this and can remove that code from your example.
Anyway, to set this up you'll need a div to append the dropdown menu and a set of stock names. You can use this list of stock names to create the dropdown menu as shown below.
var names = ["AAPL", "YHOO", "FB", "MSFT"];
d3.select("#dropDown")
.append("select")
.on("change", function() {
change(this.options[this.selectedIndex].__data__);
})
.selectAll("option")
.data(names).enter()
.append("option")
.text(function(d) {
return d;
});
Of course you need to setup the change function, which needs to wrap up all the variables required to do the call to Yahoo. Obviously, you'll need to pass in the stock parameter and once you've received the json back from Yahoo you'll need to call your draw function. So borrowing from your code something like this should work:
function change(stock) {
var url = 'http://query.yahooapis.com/v1/public/yql';
var startDate = '2013-09-06';
var endDate = '2014-03-06';
// NB the inclusion of the stock parameter
var req = encodeURIComponent('select * from yahoo.finance.historicaldata where symbol in ("' + stock + '") and startDate = "' + startDate + '" and endDate = "' + endDate + '"');
var data = $.getJSON(url, 'q=' + req + "&env=http%3A%2F%2Fdatatables.org%2Falltables.env&format=json", draw);
}
You'd have to call the draw function on load otherwise you'll end up with a blank screen and also sort out transitioning from one data set to the next.

Categories

Resources