Highstock export csv based on data grouping (export-data module) - highcharts

Currently, the export-data module exports all the series data rather than processedXData and processedYData. However, I grouped the series with dataGrouping and I'd like to export only the processed data.
I'm aware that this question has been asked before (Highstock export csv based on data grouping), but it was in the context of the former export-cvs plugin.
How to modify the 'getDataRows' function in the export-data module for including only the processed data?
Example -> fiddle
Highcharts.getJSON("https://cdn.jsdelivr.net/gh/highcharts/highcharts#v7.0.0/samples/data/usdeur.json",function (data) {
var chart = Highcharts.stockChart("container", {
series: [{
name: "The series",
data: data,
dataGrouping: {
force: true,
units: [["year", [1]]]
}
}
]
});
console.log(chart.getDataRows());
}
);

Related

How to set default zoom to 6 months using highcharts-react?

I have a couple of highcharts-react charts where the default zoom level should be 6 months (for the x-axis). There's a solution for using the default Highcharts library, but I don't understand how to do it using React.
This is how far I got:
// …
import Highcharts from "highcharts/highstock";
import HighchartsReact from "highcharts-react-official";
import more from "highcharts/highcharts-more";
// …
if (typeof Highcharts === "object") {
more(Highcharts);
}
// …
<HighchartsReact
highcharts={Highcharts}
constructorType={"stockChart"}
options={{
credits: {
enabled: false
},
xAxis: {
events: {
setExtremes: () => {
// Is this right? What should be in this function?
}
}
},
series: [
{
type: "candlestick",
name: props.timeSeries.name,
data: openHighLowClose
}
]
}}
/>
I see that you are creating a stockChart, so in this case you can set the displaying range with using the rangeSelector feature.
Below is a demo where I set the selected button to 2, which is equal to 6 months by default. More information you can find in the API which I posted above.
Demo: https://codesandbox.io/s/highcharts-react-demo-yjtgj

Jquery Autocomplete unable to read Array of Objects

I am trying to use a JSON output from the server as the source for my autocomplete function. I read the Autocomplete documentation and it does say that Array of Objects is accepted as a source type. Can someone please let me know where am I going wrong with this?
jq( document ).ready(function() {
jq("body").css({overflow:'hidden'});
jq.getJSON("<?php echo Mage::getBaseUrl() . "setsession/index/getarea"; ?>",
function(data) {
jq( "#autocomplete-1" ).autocomplete({
source: data,
select: function(event, ui) {
alert(ui.item.area_id);
jq("#splash_area").val(ui.item.area_id);
return false;
}
});
}
);
});
This is what I am getting back from the server (JSON encoded):
[{"area_id":"1","area_name":"DLF Phase 1"},{"area_id":"2","area_name":"DLF Phase 2"}]
From the documentation it states an An array of objects with label and value properties: [ { label: "Choice1", value: "value1" }, ... ].
http://api.jqueryui.com/autocomplete/#option-source
Your objects are not defined this way. So for your example something like
[{value:"1",label:"DLF Phase 1"},{value:"2",label:"DLF Phase 2"}]

Displaying huge amount of data (in json object) in Kendo UI tree view. Give stack overflow error with huge records

I need to display all the records in a kendo view tree view at one go. Means at load of tree, I want all the nodes of my hierarchical data to be displayed. When data is less, I am getting no issue. But when my data is high, I am getting stack overflow error at line number:3, say.
When I debug the visual studio code, I get : "0x800a001c - Microsoft JScript runtime error: Out of stack space"
Actually what is happening, when a child node is displayed, kendo checks for the parent node. So if we have multiple child nodes, recursive calls are happening to get the parent node. With huge data, recursive calls are huge. Hence getting stack overflow error. Can anyone here help me out what I should change in my code.
I am using MVC for this. And 'treeData' contains json data.
The data is coming from the service in hierarchical format.
_intializeStudentTree: function () {
var abc = this;
var treeData = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: "controller1/method1",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8"
},
parameterMap: function (options) {
options['StudentID'] = abc.options.list.StudentId;
options['StudentDetails'] = abc.options.list.StudentDetails;
return JSON.stringify(options);
}
},
schema: {
model: {
children: "ChildRecords"
}
}
});
abc.subscriptionListTree = abc.element.find('.tree-view').kendoTreeView({
template: kendo.template($("#temp-treeview").html()),
animation: {
expand:false
},
dataSource: treeData,
dataTextField: ["StudentLevel"],
loadOnDemand: false,
dataBound: function () {
thiz.subscriptionListTree.expand(".k-item");
}
}).data('kendoTreeView');
},

Putting data from a database into highcharts using $.getJSON

I'm having some problems with $.getJSON, I really need some help because I don't know how to solve the problem and I've been stuck here for days. This is the js file that should generate highcharts when selecting a select option in HTML:
$(document).ready(function() {
$("#paese").change(function(){
var seriesOptions = [];
$.getJSON("prova.php", function(data) {
seriesOptions = data;
});
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
spacingLeft: 20,
borderWidth: 1
},
....
series: [{
name: 'Italia',
data: seriesOptions
}],
Is there anything wrong in the first part? When I select an option, it seems like highcharts don't get the php file, but I'm pretty sure it's correct, here it is(PHP file):
<?PHP
header("Content-Type: application/json; charset=UTF-8");
$conn = mysql_connect("localhost", "root");
$paese = null;
if(isset($_GET['paese'])) $paese = $_GET['paese'];
$ok = mysql_select_db("liberta", $conn);
$response = array();
$sql="SELECT `valori`.Punteggio FROM `valori` INNER JOIN `nazioni` ON `valori`.Nazione
= `nazioni`.ID WHERE `nazioni`.Nome = '$paese'";
$res=mysql_query($sql);
while($record=mysql_fetch_row($res)){
$response[] = intval("$record[0]");
}
mysql_close($conn);
print(json_encode($response));
I'm trying to get the data from a database I created with PHPmyadmin and put them directly into highcharts, but it doesn't work. I'd be very pleased if you could help me, also because this is is an exam I have to sit. Thank you very much.
I advice to familair with article about preprocessing data http://docs.highcharts.com/#preprocessing.
You need to have strucuture like:
{
data:[1,2,3]
}
Try to replace
while($record=mysql_fetch_row($res)){
$response[] = intval("$record[0]");
}
with
while($record=mysql_fetch_row($res)){
$response['data'][] = intval($record[0]);
}
Your problem is with the javascript part. When you call $.getJSON, the callback you provide will be called asynchronously when the server responds. Howether in your code you are calling the Highcharts() constructor immediately in a synchronous way. At the point its called the seriesOption variable still equals to []. Try calling the constructor from the callback like this:
$.getJSON("prova.php", function(data) {
var chart1 = new Highcharts.Chart(....
series: [{
name: 'Italia',
data: data}])});

Manage multiple highchart charts in a single webpage

I am having multiple highchart charts of various types(Bar,Pie, Scatter type) in a single web page. Currently I am creating config object for each graph like,
{
chart : {},
blah blah,
}
And feeding them to a custom function which will just call HighCharts.chart(). But this results in duplication of code. I want to manage all this chart rendering logic centrally.
Any Idea on how to do this?
You can use jQuery.extend() and Highcharts.setOptions.
So first you'll make the first object which will be extended by all your charts, this object will contain your Highchart default functions.
You can do it using namespacing.
The following way is good when you have very different charts.
Default graphic:
var defaultChart = {
chartContent: null,
highchart: null,
defaults: {
chart: {
alignTicks: false,
borderColor: '#656565',
borderWidth: 1,
zoomType: 'x',
height: 400,
width: 800
},
series: []
},
// here you'll merge the defauls with the object options
init: function(options) {
this.highchart= jQuery.extend({}, this.defaults, options);
this.highchart.chart.renderTo = this.chartContent;
},
create: function() {
new Highcharts.Chart(this.highchart);
}
};
Now, if you want to make a column chart, you'll extend defaultChart
var columnChart = {
chartContent: '#yourChartContent',
options: {
// your chart options
}
};
columnChart = jQuery.extend(true, {}, defaultChart, columnChart);
// now columnChart has all defaultChart functions
// now you'll init the object with your chart options
columnChart.init(columnChart.options);
// when you want to create the chart you just call
columnChart.create();
If you have similar charts use Highcharts.setOptions which will apply the options for all created charts after this.
// `options` will be used by all charts
Highcharts.setOptions(options);
// only data options
var chart1 = Highcharts.Chart({
chart: {
renderTo: 'container1'
},
series: []
});
var chart2 = Highcharts.Chart({
chart: {
renderTo: 'container2'
},
series: []
});
Reference
http://api.highcharts.com/highcharts#Highcharts.setOptions%28%29
COMPLETE DEMO
I know this has already been answered, but I feel that it can be taken yet further. I'm still newish to JavaScript and jQuery, so if anyone finds anything wrong, or thinks that this approach breaks guidelines or rules-of-thumb of some kind, I'd be grateful for feedback.
Building on the principles described by Ricardo Lohmann, I've created a jQuery plugin, which (in my opinion) allows Highcharts to work more seamlessly with jQuery (i.e. the way that jQuery works with other HTML objects).
I've never liked the fact that you have to supply an object ID to Highcharts before it draws the chart. So with the plug-in, I can assign the chart to the standard jQuery selector object, without having to give the containing <div> an id value.
(function($){
var chartType = {
myArea : {
chart: { type: 'area' },
title: { text: 'Example Line Chart' },
xAxis: { /* xAxis settings... */ },
yAxis: { /* yAxis settings... */ },
/* etc. */
series: []
},
myColumn : {
chart: { type: 'column' },
title: { text: 'Example Column Chart' },
xAxis: { /* xAxis settings... */ },
yAxis: { /* yAxis settings... */ },
/* etc. */
series: []
}
};
var methods = {
init:
function (chartName, options) {
return this.each(function(i) {
optsThis = options[i];
chartType[chartName].chart.renderTo = this;
optsHighchart = $.extend (true, {}, chartType[chartName], optsThis);
new Highcharts.Chart (optsHighchart);
});
}
};
$.fn.cbhChart = function (action,objSettings) {
if ( chartType[action] ) {
return methods.init.apply( this, arguments );
} else if ( methods[action] ) {
return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
} else if ( typeof action === 'object' || !action ) {
$.error( 'Invalid arguments to plugin: jQuery.cbhChart' );
} else {
$.error( 'Action "' + action + '" does not exist on jQuery.cbhChart' );
}
};
})(jQuery);
With this plug-in, I can now assign a chart as follows:
$('.columnChart').cbhChart('myColumn', optionsArray);
This is a simplistic example of course; for a real example, you'd have to create more complex chart-properties. But it's the principles that concern us here, and I find that this approach addresses the original question. It re-uses code, while still allowing for individual chart alterations to be applied progressively on top of each other.
In principle, it also allows you to group together multiple Ajax calls into one, pushing each graph's options and data into a single JavaScript array.
The obligatory jFiddle example is here: http://jsfiddle.net/3GYHg/1/
Criticism welcome!!
To add to #Ricardo's great answer, I have also done something very similar. In fact, I won't be wrong if i said I went a step further than this. Hence would like to share the approach.
I have created a wrapper over the highchart library. This gives multiple benefits, following being the main advantages that encouraged going in this path
Decoupling: Decouples your code from highcharts
Easy Upgrades: This wrapper will be the only code that will require modification in case of any breaking changes in highchart api after upgrades, or even if one decides to move to a differnt charting library altogether (even from highchart to highstock can be exhaustive if your application uses charts extensively)
Easy of use: The wrapper api is kept very simple, only things that may vary are exposed as options (That too whose values won't be as a deep js object like HC already has, mostly 1 level deep), each having a default value. So most of the time our chart creation is very short, with the constructor taking 1 options object with merely 4-5 properties whose defaults don't suit the chart under creation
Consistent UX: Consistent look & feel across the application. eg: tool tip format & position, colors, font family, colors, toolbar (exporting) buttons, etc
Avoid duplication: Of course as a valid answer of the asked question it has to avoid duplication, and it does to a huge extent
Here is what the options look like with their default values
defaults : {
chartType : "line",
startTime : 0,
interval : 1000,
chartData : [],
title : "Product Name",
navigator : true,
legends : true,
presetTimeRanges : [],
primaryToolbarButtons : true,
secondaryToolbarButtons : true,
zoomX : true,
zoomY : false,
height : null,
width : null,
panning : false,
reflow : false,
yDecimals : 2,
container : "container",
allowFullScreen : true,
credits : false,
showAll : false,
fontSize : "normal", // other option available is "small"
showBtnsInNewTab : false,
xAxisTitle : null,
yAxisTitle : null,
onLoad : null,
pointMarkers : false,
categories : []
}
As you can see, most of the times, its just chartData that changes. Even if you need to set some property, its mainly just true/false types, nothing like the horror that highchart constructor expects (not critizing them, the amount of options they provide is just amazing from customization Point of View, but for every developer in the team to understand & master it can take some time)
So creation of chart is as simple as
var chart=new myLib.Chart({
chartData : [[1000000,1],[2000000,2],[3000000,1],[4000000,5]]
});

Resources