HighCharts, multiple charts on page call via function - javascript
Hopefully someone can help me as I'm stuck at the moment after searching for a solution already for the last 2 days.
I decided to look into HighCharts yesterday for a new project and it does do what I'm after. However I'm trying to make the implementation option into my WordPress plugin as clean as possible and that's where I'm stuck at the moment.
This JSFiddle is working and shows what I like to get as output: http://jsfiddle.net/golabs/tpKU3/
But I would like to be able to create a new chart by just calling a function and supply the target div ID and the 2 dataArray's. My attempt can be found here: http://jsfiddle.net/golabs/rstpA/
or see the jscode here:
/**
* However this second section of code does NOT work as nothing is displayed in the container21 div...
* What am I doing wrong here?
* I like to be able to create a new chart by only supplying the target div ID and the dataArray's, this
* to have be able to manage the general settings centrally.
*
* This JSFIDDLE is related to: http://jsfiddle.net/golabs/tpKU3/
**/
$(function () {
var __catergories__ = ['AAA','BBB','CCC','DDD','EEE','FFF','GGG'];
var getChartConfig = function( renderId, dataArray1, dataArray2 ) {
var config = {};
config.chart = {
renderTo: renderId, polar: true, type: 'line', height: 254, width: 360, className: 'SpiderPolarChart', backgroundColor: 'rgba(101,101,101,.1)'
};
config.title = {
text: ''
};
config.legend = {
layout: 'horizontal', align: 'center', verticalAlign: 'bottom', y: -3,
};
config.credits = {
enabled: true, text: 'highcharts.com', href: 'http://highcharts.com/', position: {
verticalAlign: 'bottom',
x: -11,
}
};
config.pane = {
startAngle: -90, endAngle: 90, center: ['50%', '93%'], size: 300, background: null
};
config.xAxis = {
categories: __catergories__,
tickmarkPlacement: 'on', tickPixelInterval: 1, lineWidth: 0, labels: {
rotation: 'auto',
distance: 12
}, showLastLabel: true
};
config.yAxis = {
gridLineInterpolation: 'circle', gridLineDashStyle: 'LongDash', tickInterval: 1, lineWidth: 0, min: 0, max: 5, ceiling: 5, labels: {
x: 4, y: 15
}, showLastLabel: true
};
config.exporting = {
enabled: false
};
config.tooltip = {
shared: true, pointFormat: '<span style="color:{series.color}">{series.name}: <b>{point.y:,.0f}</b><br/>'
};
config.series = [{
name: 'Overall Rating', data: dataArray1, color: '#D4A539', type: 'area', pointPlacement: 'on', connectEnds: false, index: 1, legendIndex: 2
},{
name: 'Personal Rating', data: dataArray2, color: '#333', type: 'line', pointPlacement: 'on', connectEnds: false, index: 2, legendIndex: 1
}];
return config;
};
// ===========================================================================
charts.push(new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
});
I've run the code through JSHint.com so all typos should be tackled as it doesn't show any errors at the moment.
I hope someone can guide me into the right direction to get this to work.
Cheers!
** Updated the links to the JSFiddles **
** ISSUE RESOLVED, see below **
In this jsFiddle (http://jsfiddle.net/golabs/rstpA/) you are not telling it what chart is. You are trying to set the options for a chart that you have not created to update the options you are passing. It is sort of backwards.
Here is a quick "fix":
var newChart = new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
);
Now, I would think it would be better to setup a global option set and then merge in your new set (specific to chart you want to build) as in my linked SO answer. This may or may not give you more flexibility.
charts was not defined.
Is this the solution you are looking for?
var charts = [];
charts.push(new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
http://jsfiddle.net/37Gsv/1/
you may try this:
var charts = [];
var i=0;
for (i =1; i< 10; i++){
var o =i.toString();
charts.push(new Highcharts.Chart(
getChartConfig( "container2"+o, [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
}
test link: http://jsfiddle.net/newpiseth/8u0tkkkL/5/
Related
Pass data to Stacked Column Chart (Highcharts Framework)
I have a problem when trying to render a stacked column chart with the Highcharts framework. I get an error when rendering on the client: Uncaught TypeError: a.toPrecision is not a function From what I've gathered this is related with stacking. If I set stacking to null it won't give an error, but no graph will show. I'm passing dynamic data to the series. The data is in the form of a name for the legend and an array of values for each xAxis category. Below is an example of one object that is passed as data. This is stored in an array with a more entries. name:"READ_CALENDAR" y: (24) [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] This must be the wrong way, since I can't get it to work, but what then is the correct way? My question is, what am I doing wrong? How should I pass dynamic data to make it work? I need to pass several unique instances of data that need to stack and match the xAxis categories. I will add more details below regarding how I pass data and such. If you want more info comment and I will try to provide as much as I can. Please help! Thanks in advance!!! This is an example of data that is passed to the client: [{"name":"READ_CALENDAR","timesUsed":[1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0]}, {"name":"READ_CONTACTS","timesUsed":[1,0,0,0,0,0,0,0,0,0,0,0,5,8,12,3,2,0,1,0,0,0,0,0]}, {"name":"READ_EXTERNAL_STORAGE","timesUsed":[1,0,0,0,0,0,0,0,0,10,0,1,9,17,13,39,8,1,0,0,0,0,0,2]}, {"name":"WRITE_EXTERNAL_STORAGE","timesUsed":[1,0,0,0,0,0,0,0,0,10,0,2,9,17,13,38,8,1,0,0,0,0,0,2]}, {"name":"WRITE_SMS","timesUsed":[1,0,0,0,0,0,0,0,0,0,0,0,5,7,12,2,2,1,0,0,0,0,0,0]}, {"name":"CAMERA","timesUsed":[0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,2,1,0,0,0,0,0,0]}, {"name":"FINE_LOCATION","timesUsed":[0,0,0,0,0,0,0,0,0,15,4,0,0,0,0,2,0,0,0,0,0,0,0,0]}, {"name":"GPS","timesUsed":[0,0,0,0,0,0,0,0,0,3,0,0,0,1,1,2,0,0,0,0,0,0,0,0]}, {"name":"MONITOR_HIGH_POWER_LOCATION","timesUsed":[0,0,0,0,0,0,0,0,0,4,0,0,0,1,1,2,0,0,0,0,0,0,0,0]}, {"name":"MONITOR_LOCATION","timesUsed":[0,0,0,0,0,0,0,0,0,3,0,0,0,1,1,2,0,0,0,0,0,0,0,0]}, {"name":"OP_READ_PHONE_STATE","timesUsed":[0,0,0,0,0,0,0,0,0,2,0,0,3,2,1,3,0,2,0,0,0,0,0,0]}, {"name":"POST_NOTIFICATION","timesUsed":[0,0,0,0,0,0,0,0,0,16,15,7,10,14,26,17,5,2,1,0,0,0,0,0]}, {"name":"TAKE_AUDIO_FOCUS","timesUsed":[0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0]}, {"name":"TOAST_WINDOW","timesUsed":[0,0,0,0,0,0,0,0,0,14,15,7,10,9,13,12,3,1,0,0,0,0,0,0]}, {"name":"WAKE_LOCK","timesUsed":[0,0,0,0,0,0,0,0,0,6,0,0,1,3,2,17,7,2,0,0,0,0,0,1]}, {"name":"WIFI_SCAN","timesUsed":[0,0,0,0,0,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0]}, {"name":"BOOT_COMPLETED","timesUsed":[0,0,0,0,0,0,0,0,0,0,0,0,4,2,0,0,0,0,0,0,0,0,0,0]}, {"name":"GET_ACCOUNTS","timesUsed":[0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,3,0,0,0,0,0,0,0,0]}, {"name":"WIFI_CHANGE","timesUsed":[0,0,0,0,0,0,0,0,0,0,0,0,4,2,0,0,0,0,0,0,0,0,0,0]}, {"name":"USE_FINGERPRINT","timesUsed":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0]}, {"name":"RECORD_AUDIO","timesUsed":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0]}, {"name":"VIBRATE","timesUsed":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,0,0,0,0,0,0,0]}, {"name":"WRITE_CALENDAR","timesUsed":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0]}] This data will then be parsed to a JSON Object with: var jsonObj = JSON.parse(obj); (where obj is the data) Then the the data will be pushed to an array: var seriesData = []; for (var i in jsonObj) { seriesData.push({ name: jsonObj[i].name , y: jsonObj[i].timesUsed }); } Then the Hichcharts scripts looks like this: Highcharts.chart('permData', { chart: { type: 'column' }, title: { text: 'Example graph' }, xAxis: { categories: ['00-01','01-02','02-03','03-04','04-05','05-06','06-07','07-08','08-09','09-10','10-11','11-12','12-13','13-14','14-15','15-16','16-17','17-18','18-19','19-20','20-21','21-22','22-23','23-24'] }, yAxis: { min: 0, title: { text: 'Y axis text here' }, stackLabels: { enabled: true, style: { fontWeight: 'bold', color: null /*(Highcarts.theme && Highcharts.theme.textColor) || 'gray'*/ } } }, legend: { align: 'right', x: -30, verticalAlign: 'top', y: 25, floating: true, backgroundColor: null /*(Highcharts.theme && Highcharts.theme.background2) || 'white'*/, borderColor: '#CCC', borderWidth: 1, shadow: false }, tooltop: { headerFormat: '<b>{point.x}</b><br/>', pointFormat: '{series.name}:{point.y}<br/>', }, plotOptions: { column: { stacking: 'percentage', dataLabels: { enabled: true, color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white' } } }, series: [{ type: 'column', name: 'perm', data: seriesData }] });
You were very close, you have set y instead of data in your loop building the dataSeries. It should be like this: for (var i in jsonObj) { seriesData.push({ name: jsonObj[i].name , data: jsonObj[i].timesUsed //data instead of y }); } After changing that, it works in the fiddle. y is a member of data, and is used in case you want to set several properties for each point. Working example: https://jsfiddle.net/ewolden/r5yd56eb/1/ API on series.data: https://api.highcharts.com/highcharts/series.column.data
Highcharts Map not rendering no errors
I am attempting to take the example produced by Highcharts here http://www.highcharts.com/maps/demo/color-axis and substitute the data loaded by the $.getJson with a local JSON file called 'testdata1.json'. The code I've modified below produces no errors yet the map does not render. I think it's because the testdata1.json is loaded late, after the javascript is executed. If so, is there a better way I should be doing this -- perhaps waiting for the data to load before executing the JS file? I attempted to do this by placing a $(document).ready( in front of the function but it didn't work. Any thoughts are greatly appreciated, I think it's something relatively minor that is just escaping me. Thank you. $(function () { // Map options var options = { chart : { renderTo: '#map', borderWidth : 1 }, title : { text : 'US population density (/km²)' }, legend: { layout: 'horizontal', borderWidth: 0, backgroundColor: 'rgba(255,255,255,0.85)', floating: true, verticalAlign: 'top', y: 25 }, mapNavigation: { enabled: true }, colorAxis: { min: 1, type: 'logarithmic', minColor: '#EEEEFF', maxColor: '#000022', stops: [ [0, '#EFEFFF'], [0.67, '#4444FF'], [1, '#000022'] ] }, series : [{ animation: { duration: 1000 }, mapData: Highcharts.maps['countries/us/us-all'], joinBy: ['postal-code', 'code'], dataLabels: { enabled: true, color: 'white', format: '{point.code}' }, name: 'Population density', tooltip: { pointFormat: '{point.code}: {point.value}/km²' } }] }; $.getJSON('static/data/testdata1.json', function (data) { // Make codes uppercase to match the map data $.each(data, function () { this.code = this.code.toUpperCase(); }); options.series.data= data; var chart = new Highcharts.Chart(options) }); });
You have three problems. Here's a fiddle based on their sample that uses your approach, but still uses their data, and works: http://jsfiddle.net/g29k24vw/1/ Here are the important parts: chart : { renderTo: 'container', borderWidth : 1, type: 'map' }, And: $.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=us-population-density.json&callback=?', function (data) { // Make codes uppercase to match the map data $.each(data, function () { this.code = this.code.toUpperCase(); }); options.series[0].data= data; var chart = new Highcharts.Chart(options); }); Note the differences here: You need to specify the chart type in options if you're going to instantiate the chart object directly instead of using the jQuery helper. renderTo doesn't want a hash in front of the element name. options.series[0].data, not options.series.data...series is actually an array of objects.
Javascript+Highcharts: Substituting series.data for my own
I've been doing this script for a volunteering university-site job. Please ignore all parameters apart from wattages and schools. Those are SQL result sets that have been converted to arrays using json_encode(). Result sets have Strings as values, I believe, so both wattages and schools should be arrays of strings. What I want to do is input my own data for the pie graph, in this case mySeries, which I build/fill up at the start and put as data later. function createPieChartGradient(data,title,xlabel,ylabel,type,step,div_id,wattages,schools){ var float_watt = new Array(); for(var index = 0; index < wattages.length; index++) { float_watt[index] = parseFloat(wattages[index]).toFixed(2); } var mySeries = []; //Hopefully this creates a [String, number] array that can be used as Data. for (var i = 0; i < float_watt.length; i++) { mySeries.push([schools[i], float_watt[i]]); } var options = { chart: { renderTo: 'graph', zoomType: 'x', defaultSeriesType: type }, title: { text: 'Consumption Percentage of IHU Schools, Last 7 days' }, tooltip: { //pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' }, xAxis: { categories: [], tickPixelInterval: 150, // maxZoom: 20 * 1000, title: { style: { fontSize: '14px' }, text: xlabel }, labels: { rotation: -45, step: step, align: 'right'//, // step: temp } }, yAxis: { title: { style: { fontSize: '14px' }, text: ylabel }, labels: { align: 'right', formatter: function() { return parseFloat(this.value).toFixed(2); } }, min: 0 }, legend: { layout: 'vertical', align: 'right', verticalAlign: 'center', floating: true, shadow: true }, series: [{ type: 'pie', name: 'Consumption Percentage', data: mySeries //Problematic line. }] //Faculty with the smallest wattage -> Green. }; //end of var options{} //Next: -> Yellow. //Last -> Red. //Draw the chart. var chart = new Highcharts.Chart(options); //TODO: Change colours. document.write("FINISHED"); } The thing is, the above won't work. Since I'm not using an environment (writing in notepad++ and testing on my apache web server, via the results) I have manually aliminated the problematic line to be data: mySeries. Any idea why that is? Aren't they the same type of array, [String, number]? Additionally, are there any environments that will help me debug javascript programs? I'm really at my wit's end with this situation and I'd very much prefer to have an IDE tell me what's wrong, or at least point me at the right direction.
You see where you are calling "toFixed"? Let's run a small experiment: var wattages = [2.0, 3.0]; var float_watt = new Array(); for(var index = 0; index < wattages.length; index++) { float_watt[index] = parseFloat(wattages[index]).toFixed(2); } console.log(JSON.stringify(float_watt)); The output is not what you expect: ["2.00", "3.00"] See how it got converted to a string? If you delete the "toFixed" and let your formatter do its job, things will go just fine. EDIT Here's how you fix your formatter: plotOptions: { pie: { dataLabels: { formatter: function() { return parseFloat(this.y).toFixed(2); } } } }, The yLabels formatter is doing nothing for the pie.
Highcharts - Exporting Module
I am using highcharts to generate graphical data pulled from a database. I am having trouble using the exporting module. I have included the exporting property: exporting{ enabled:true } but the buttons do not appear... I have also linked the exporting.js to the file too...no buttons appear.. Has anyone else had this issue? EDIT: Here is the code: $.ajax({ type:"POST", url: "retrievechartdata.php", data: {questionId:qId, questionIdTwo:qIdTwo, title:title, titleTwo:titleTwo, from:from, to:to}, dataType: "json", success: function(data) { //$("#response").html("<div class='successMessage'>"+ data.valuesTwo +"</div>"); var maxY = parseInt(data.max) + 1; var minY = parseInt(data.min); if(minY > 0){ minY = 0; }else{ minY -= 1; } var cdata = new Array(); cdata= data.values.split(','); for(var i=0;i<cdata.length;i++) { cdata[i]= parseInt(cdata[i]); } var leg = false; var title = data.questionTitle; if(data.valuesTwo != "FALSE"){ leg = true; title += " & "+data.questionTitleTwo; var cdataTwo = new Array(); cdataTwo = data.valuesTwo.split(','); for(var i=0;i<cdataTwo.length;i++) { cdataTwo[i]= parseInt(cdataTwo[i]); } } chart = new Highcharts.Chart({ chart: { renderTo: 'container', zoomType: 'x', spacingRight: 20 }, credits: { enabled: false }, title: { text: title }, subtitle: { text: document.ontouchstart === undefined ? 'Click and drag in the plot area to zoom in' : 'Drag your finger over the plot to zoom in' }, xAxis: { type: 'datetime', maxZoom: 14 * 24 * 3600000, // fourteen days lineWidth: 1, lineColor: '#999999', title: { text: 'Date' } }, yAxis: { title: { text: data.questionTitle }, labels: { y: 2 }, lineWidth: 1, lineColor: '#999999', gridLineWidth: 1, gridLineColor: '#eaeaea', min: minY, max: maxY, startOnTick: false, showFirstLabel: false }, tooltip: { shared: true }, legend: { enabled: leg }, plotOptions: { area: { Color: { linearGradient: [0, 0, 0, 600], stops: [ [0, 'rgb(69, 114, 167)'], [1, 'rgba(2,0,0,0)'] ] }, lineWidth: 1, marker: { enabled: false, states: { hover: { enabled: true, radius: 5 } } }, shadow: false, states: { hover: { lineWidth: 1 } } } }, series: [{ type: 'spline', name: data.questionTitle, pointInterval: 24 * 3600 * 1000, pointStart: Date.UTC(data.year, data.month, data.day), data: cdata, lineColor: '#f6a828', color: '#418ed6' }, { type: 'spline', name: data.questionTitleTwo, pointInterval: 24 * 3600 * 1000, pointStart: Date.UTC(data.year, data.month, data.day), data: cdataTwo, lineColor: '#808080', color: '#ff0000' }], exporting: { enabled: true } })
Which version of Highcharts you are using? Which version of jQuery? Currently is the v2.1.6, I recommend you use the latest release because they are continuously fixing bugs, adding new functionality, etc. Prior to v2.0 there is no support to the exporting feature The only things you need to do in order to bring the exporting module working are: 1- First: Add the js script after the highcharts script, like this: ... <script type="text/javascript" src="../js/highcharts.js"></script> <!-- 1b) Optional: the exporting module --> <script type="text/javascript" src="../js/modules/exporting.js"></script> ... The exporting module is enabled by default, so there is no need to have the code you posted, so you can remove it: exporting{ enabled:true } 2- Second: Be sure to publish the exporting-server/index.php file correctly. Here you have what the official documentation reads about the exporting module installation: Exporting module From version 2.0 an exporting module is available for Highcharts, which allows users to download images or PDF's of your charts. This module consists of an extra JavaScript file, exporting.js, and a web service or server module written in PHP. Highslide Software offers the exporting web service free of charge. If you include the exporting module in your charts, two buttons will appear in the upper right. One button prints the chart, which is done on the client side only. The other button handles exporting. By default, an SVG representation of the chart is sent by POST to http://export.highcharts.com, where it is converted using Apache's Batik converter to PDF, PNG or JPEG. See the navigation and exporting reference items for a full documentation for the options available. Also see under "Methods and Properties" in the reference for members releated to exporting. Here you can see the configuration options regarding the exporting module: http://www.highcharts.com/ref/#exporting Hope it helps you.
Make sure the script tag has type="text/javascript"
jqplot bargraph not displaying data
Not getting any errors from firebug. Not showing in any browser. Was working previously and stopped working about a week ago. Sample of the code... $(document).ready(function () { //Generic names for multiple graphs var First = $('#hfFirstOrder').val().split(","); var Second = $('#hfSecondOrder').val().split(","); var Third = $('#hfThirdOrder').val().split(","); var ticks = $('#hfDaysOrder').val().split(","); var maxValue = parseInt($('#hfMaxOrder').val()); var FirstArray = []; var SecondArray = []; var ThirdArray = []; for (i = 0; i < First.length; i++) { FirstArray.push(parseInt(First[i])); SecondArray.push(parseInt(Second[i])); ThirdArray.push(parseInt(Third[i])); } plotGraph("stackedPurchase", [FirstArray, SecondArray, ThirdArray], true, ticks, "Orders", maxValue, '#000', "Completed", '#00F', "Ship/Pick", '#F00', "Back Order"); function plotGraph(chartName, total, stackBool, tick, yLabel, maxValue, SC1, SL1, SC2, SL2, SC3, SL3) { plot = $.jqplot(chartName, total, { stackSeries: stackBool, seriesDefaults: { renderer:$.jqplot.BarRenderer, rendererOptions: { barMargin: 20, barWidth: 10 }, showMarker: false, pointLabels: { show: false } }, axes: { xaxis: { label: "Days", renderer: $.jqplot.CategoryAxisRenderer, ticks: tick }, yaxis: { label: yLabel, padMin: 0, tickInterval: parseInt(maxValue * .1), min: 0, max: maxValue, tickOptions: { formatString: '%d' } } }, series: [{ color: SC1, label: SL1 }, { color: SC2, label: SL2 }, { color: SC3, label: SL3 } ], legend: { show: true, location: 'e', placement: 'outside' } }); } }); And then there's a call in the html for <div id="stackedPurchase" style="height:450px;width:900px;" runat="server"></div> And the various hidden values are csv strings from the code behind. According to firebug they are being passed in correctly (right formats and correct number of each variable). Judging from my coding experiences recently, its probably something obvious.
Got a partial answer, the first two graphs work now because someone else at work moved the folders that the jqplot stuff was in without informing me. Changing the address in the scripts at top fixed the problem. But for some reason the third one isn't working. plotGraph("graphQuote", [FirstArray, SecondArray, ThirdArray], false, ticks, "Quotes", maxValue, '#F00', "Request RFQ", '#00F', "RFQ", '#0F0', "Customer Quote"); SecondArray is all zero values, FirstArray is mostly zero and ThirdArray has a value in most of its fields. Ticks has correct dates.
Alright, found the problem. Apparently parseInt(maxValue * .1) gets pissy and returns 0 if maxValue is less than 10, and jqplot doesn't like 0 as a tick interval. Found a better way to do intervals and now everything works.