I'm using HighCharts library to plot some data in gauge chart. My chart looks like the image below.
To achieve this plot, I'm using solid gauge and gauge together using series option, (solid gauge for the semicircular and gauge for the dial.)
...
series: [
{
name: 'solidgauge',
type: 'solidgauge',
data: [data.value],
...
},
{
name: 'gauge',
type: 'gauge',
data: [data.value],
...
},
]
...
Obviously the data for both series is identical, so when I export the chart into csv file, the library create two columns with same data and I want to change this behavior and export only one of series, but after a lots of search, I couldn't find any option in highcharts to exclude a specific series.
How can I do that? (I'm not familiar with exporting customization, answer with little code sample would be great for start creating my own.)
You can wrap the getCSV method and hide the series befere the proceed:
var H = Highcharts;
H.wrap(H.Chart.prototype, 'getCSV', function(proceed) {
var result;
this.series[1].hide();
result = proceed.apply(this, Array.prototype.slice.call(arguments, 1));
this.series[1].show();
return result;
});
Live demo: https://jsfiddle.net/BlackLabel/109a7vek/
Also, you can edit the generated data in the exportData event:
H.addEvent(H.Chart, 'exportData', function(e){
e.dataRows.forEach(function(el){
el.splice(2, 1);
});
});
Live demo: https://jsfiddle.net/BlackLabel/du7nz2hy/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
Related
I am struggling to understand why I cannot get the ordinal aspect of my spline type chart to work correctly! I created a series of bar charts a long time ago but having not done anything like this in years I'm a tad clueless and needing some guidance, I've spent hours trying different methods and nothing works wether using Highcharts or highstock.
The code I have in the head of my page is as follows:
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'spline'
},
title: {
text: theTitle,
x: -20
},
xAxis: {
ordinal: false,
type:'datetime',
labels: {formatter: function() {return Highcharts.dateFormat('%b %e (%y)', this.value);}}
},
series: []
}
$.getJSON("data_weight_loss.php", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
chart = new Highcharts.Chart(options);
});
});
The dates are in datestamp format in my MySQL database as "2022-06-28 09:02:45" and despite trying all sorts I'm confused to how I can get the dates in my chart to add the dates in that don't already exist?
This image shows the chart on how it currently looks but has no relevance as the dates that are missing means the chart is not very helpful. It's been a long time since I used Highcharts and even did anything like this but as a personal project I'd love to get my chart working with the ordinal aspect in place. Is there anything glaringly obvious that I have done wrong?
The data for instance is like this if I look directly in the data call from the php page.
[{"name":"Date","data":[1651695362000,1652140800000,1652227200000,1652313600000,1652400000000,1652918400000,1653264000000,1654214400000,1654473600000,1654560000000,1654819200000,1655164800000,1655251200000,1655424000000,1655683200000,1656288000000]},{"name":"Weight","data":[2188,2000,1986,1962,1948,1868,1834,1744,1728,1720,1702,1682,1676,1666,1652,1622]}]
Any help would be appreciated, thank you.
I have a datatable with a button to export its data to a pdf file using pdfmake. So far so good until I received the request to add one more value to one of the columns (and this value should not appear in the exported data). The column I'm having this problem has the following composition:
<td>{{client.lot}}<br><p>{{client.lot.total_negotiations}} client(s) negotiating!</p></td>
(Ok, I know this is not the best way to split all cells of the column into two rows)
What I'm trying to do is to export the data only with the "first row" (before the <br> tag). How can I accomplish this? There's any workaround adjusting the table or the pdf?
You can use the exportOptions.format() function provided by DataTables to do this.
For example, assuming we start with the following table data (where there are 2 cells containing data which needs to be formatted):
Then the resulting PDF will look as follows:
The DataTables configuration for this is:
$(document).ready(function() {
$('#example').DataTable( {
"dom": 'B<"clear">lfrtip',
buttons: [{
extend: 'pdf',
text: 'Save as PDF',
exportOptions: {
modifier: {
page: 'current'
},
format: {
body: function ( data, rowIdx, colIdx ) {
if (colIdx == 1) {
var brIdx = data.indexOf("<br>");
if (brIdx >= 0) {
return data.substring(0, brIdx);
} else {
return data;
}
} else {
return data;
}
}
}
}
}]
} );
} );
This uses a function to inspect the contents of each cell. In my case, I ignore any data which is not in column index 1 (the 2nd column in the table).
For each cell of data in this column, I check for the existence of a <br> tag in the data. If one exists, then all data from this tag to the end of the string is discarded.
All other cells in all other columns are passed through to the PDF unchanged.
You may need to adjust this, depending on your specific needs (e.g. if you need to handle multiple columns, maybe to clean up that trailing hyphen in "Lote 14 -", etc.).
You may want move the export logic to its own separate function, as well, and then call that function from the DataTable config instead (so the logic does not clutter the DataTable configuration code).
Background information on this export function can be found here: exportData - specifically, see the format section on that page. This is the general buttons function used by the exportOptions configuration in the above example.
I am trying to get Kendo Grid data which is hydrated from client side to a MVC controller method. My view contains several single fields like name, date of birth etc and tabular field which I hooked with a Kendo Grid. Since its a new operation I have no data in the grid ( and other fields) and user enters them from client side.
I have no idea how to proceed on this. Ideally I would like to get this data to a list in my viewmodal. So that when the user hits save, I have all other data and the grid data coming into a controller method.
I am able to successfully bind a list with kendo grid and display it. I have very little experience on JavaScript and Kendo and web programming.
If any of you can point me to the right direction, sample code would be greatly appreciated.
$("#departmet").kendoGrid({
dataSource: dataSource,
height: 250,
scrollable: true,
sortable: true,
filterable: true,
pageable: {
input: true,
numeric: false
},
columns: [
"DepartmentName",
"SubDivision"
]
});
From experience I know their documentation is not easy to navigate. It seems there is the documentation and then the API. The API is usually what you will always want to find. What you will need is the information from here https://docs.telerik.com/kendo-ui/api/javascript/ui/grid. If I understand the question correctly. There are several ways you can achieve posting. You could make use of editor templates. Click the Open in Dojo to get an idea how it looks.
https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/editable.template
With this you do not have to worry about modifying the data via javascript. Assuming your grid is surrounded with a form element it will get posted when submitted. Note paging is not accounted for here. Also, this method by default can auto post after each edit. If you don't want this behavior then you will have to have advanced knowledge of the API.....Correction on that last statement. The API is different when dealing with the data all on the client side. Click the Open in Dojo to see it all on the client side. If you are not wanting to use editor templates and want to manage the data editing yourself then you need to use the grid methods provided.
Once you have your grid created. To access the data source of the grid you will need to get the dataSource.
$('#departmet').data('kendoGrid').dataSource;
https://docs.telerik.com/kendo-ui/api/javascript/data/datasource
If you need to use a different data source(or change it) you can use the setDataSource method below(grid function).
https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/methods/setdatasource
To add to the data source use the add function to add a new object.
$('#departmet').data('kendoGrid').dataSource.add({ id: 2, name: 'name'});
https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/add
It is important with kendo to ALWAYS use the methods provided to change the data source so that the proper events can fire to update the UI accordingly. This includes if you need to set a property on a specific data item. In that case you need to use the set method on the item itself.
After you are done modifying your data. Within javascript get the data and either create DOM elements within a form
//JQuery sudo code example
var data = $("#departmet").data("kendoGrid").dataSource.data();
var dataLen = data.length;
var myForm = $('#my-form'); //Already within DOM
for (var i = 0; i < dataLen; i++) {
var item = data[i];
var idEl = $('<input type="hidden" name="userData[' + i + '].id" />');
idEl.val(item.id);
var nameEl = $('<input type="hidden" name="userData[' + i + '].name" />');
nameEl.val(item.name);
myForm.append(idEl);
myForm.append(nameEl);
}
myForm.submit();
This assumes your controller function(??) on the backend is expecting an array of objects with the property name of userData.
Alternatively, you can post it via ajax. For example, the ajax jquery function. Passing your data as the data of the ajax call.
http://api.jquery.com/jquery.ajax/
Don't want to ramble. Let me know if you need more help.
SO won't let me comment yet so have to add another answer. You will not need to define the data source within the .NET code when dealing with client only data. Just use this.
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
)
If you will have data coming from the backend then you need to use the generic-less constructor and pass in the object else keep what you have.
Html.Kendo().Grid(Model.MyList)
However, if you are preprocessing some client data on the screen that you want to initialize then you will need to do this on ready. Don't worry about the schema part of the data source. It already knows this when you used the .NET MVC wrapper because you gave it the schema(type) via the generic or the parameter provided.
var initialDS= new kendo.data.DataSource({
data: [
{ ActionName: "Some Name", ActionType: "Some Type" }
]
});
$(document).ready(function () {
$('#docworkflow').data('kendoGrid').setDataSource(initialDS);
});
As I mentioned in the other answer. Use the data source functions for adding additional data to the data source. No need to setDataSource each time you want to add. Just
//Assuming you have 2 inputs on the screen the user is entering info into
var nameEntry = $('#action-name').val();
var typeEntry = $('#action-type').val();
$('#docworkflow').data('kendoGrid').dataSource.add({ ActionName: nameEntry , ActionType: typeEntry });
So after some efforts I come up with. But I don't know where to specify the
data in the html code. Is it possible this way?
#(Html.Kendo().Grid <DockData.Action> ()
.Name("docworkflow")
.Columns(columns =>
{
columns.Bound(e => e.ActionName);
columns.Bound(e => e.ActionType);
}).DataSource( **How do I load a script variable here***)
//This script variable should be fed to the above code.
This variable is populatedwhen the user adds data from the UI which works fine.
var dataSource = new kendo.data.DataSource({
data: result,
schema: {
model: {
fields: {
ActionName: { type: "string" },
ActionType: { type: "string" }
}
}
},
pageSize: 20
});
I want to add some series (I get the series data from a webservice as a 3dim array (and returning it as json) - I dont know the number of series I will get, so I have to load the series data dynamically).
In javascript I am building an object: (like this highstock example: http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/stock/demo/compare/)
seriesOptions[i] = {
name: namearray[i],
data: dataarray
};
e.g. result: [Object { name="Series", data=[[1041375600000, 29,9]]}]
I was trying to add the series like this:
$.each(seriesOptions, function (itemNo, item) {
chart.addSeries({
name: item.name,
data: item.data
}, false);
});
chart.redraw();
But the chart draws the series kinda weird and doesnt convert to timestamp to date.
Are there any problems with my chart data from the webservice?
Here is my code: http://jsfiddle.net/DGdaf/2/
Thanks for any help so far.
EDIT
It seems like the chart ignoeres all the default values of timeline/zoom value.
I have no idea why it doesnt display these components.
The problem could be, that I am drawing the chart after the initialization?
chart = new Highcharts.Chart(options);
But I have to do it cause of the dynamic series loading.
EDIT2
I am not sure if I am loading too much data or something. I cant create my series dynamically.
for(i=0; i<seriesOptions.length; i++){
chart.addSeries({
name: seriesOptions[i].name,
data: seriesOptions[i].data
}, true);
};
Set for your yAxis:
yAxis: {
type: 'datetime'
}
See fiddle
EDIT:
Timeline / zoom
http://jsfiddle.net/DGdaf/5/
Edit:
Use callback to add series, when chart is ready. However, why don't you add these series when chart is created?
chart = new Highcharts.Chart(options, function(ch) {
$.each(seriesOptions, function (itemNo, item) {
ch.addSeries({
name: item.name,
data: item.data
}, false);
});
chart.redraw();
});
I am trying to work out how to update a Highcharts pie chart but for the life of me cannot seem to get it working right.
I have looked over the documentation and have been able to get a bar and line and spline graph to update fine but when using this function for pie charts it just does not work.
I am currently feeding in:
item.setData([["none", 100]], true);
Where item equals the series like so:
$.each(browser_chart.series, function(i, item){
if(item.name == 'Browser share'){
console.log(data.browsers);
item.setData([["none", 100]], true);
}
});
Which as shown in the demos is how the data for a pie chart is formatted. Problem is it cannot seem to read the series correctly. I try:
item.setData([\"none\", 100], true);
And it seems to do something but cannot read the x and y values right (which of course means it's wrong).
Can anyone here point me in the direction to get this working?
Thanks,
Edited:
When you set a new data you have to set as array of arrays for all pie parts in this case.
In my Example I have six categories, so I've to set data for all of them.
So, in this case you have to do something like:
var seriesData = [];
$.each(browser_chart.series, function(i, item) {
if(item.name == 'Browser share'){
seriesData.push(["serie"+i, someNumber]);
}
});
chart.series[0].setData(seriesData, true);
I have marked Ricardos answer however my question involved a tad more that I didn't explain properly.
I was updating the pie chart through AJAX from JSON generated by a PHP Backend. When I applied new data to the pie chart it would break.
Using Ricardos answer I was able to find out it is because I have a different number of points so I cannot just update the pie chart I must remake it like so:
browser_chart_config.series[0].data = data.browsers;
browser_chart = new Highcharts.Chart(browser_chart_config);
This will allow you to update a chart when you have a different number of points.
Hope it helps,
EDIT: I also found out that this is a known issue with HighCharts: https://github.com/highslide-software/highcharts.com/issues/542
//initialise
var new_data;
new_data = [{ name: 'load percentage', y: 10.0, color: '#b2c831' },{ name: 'rest', y: 60.0, color: '#3d3d3d' }];
function requestData()
{
$.ajax({
url: 'live-server-data.php',
success: function(point)
{
var series = chart.series[0];
var y_val = parseInt(point[1]);
var x_val = 100 - y_val;
console.log(point[0]+ "," +point[1] );//["0"]
new_data = [{ name: 'load percentage', y:y_val, color: '#b2c831' },{ name: 'rest', y:x_val, color: '#3d3d3d' }];
series.setData(new_data);
// call it again after one second
},
cache: false
});
}