New Zealand Geocoordinates Duplicated on Geochart - google-visualization
Google Geocharts seems to duplicate coordinates in New Zealand. Using this sample code:
function drawVisualization() {
var data = google.visualization.arrayToDataTable([
['Latitude', 'Longitude', 'Color', 'Size'],
[-39.3233416666667,172.68119,1,1],
[-37.328955,178.019305,1,1],
[-42.1174016666667,169.043685,1,1],
[-45.9708383333333,167.715815,1,1],
[-41.4115416666667,172.45007,1,1],
[-40.96342,173.016323333333,1,1],
[-35.3090733333333,175.540301666667,1,1],
[-34.1865233333333,173.642561666667,1,1],
[-40.9643016666667,173.015715,1,1],
[-34.963335,173.928328333333,1,1],
[-37.0131966666667,177.790023333333,1,1],
[-40.2057266666667,172.339355,1,1],
[-44.981545,170.140106666667,1,1],
[-39.260695,175.11762,1,1],
[-38.0657633333333,175.641418333333,1,1],
[-44.9679916666667,168.653268333333,1,1],
[-41.87978,171.869228333333,1,1],
[-40.5422366666667,173.954698333333,1,1],
[-35.610825,174.72943,1,1],
[-37.613945,178.318931666667,1,1],
[-45.977555,170.093883333333,1,1],
[-33.482955,172.83993,1,1],
[-42.0265716666667,171.297201666667,1,1],
[-40.7790166666667,173.082521666667,1,1],
[-37.753235,178.31691,1,1],
[-36.39364,178.314605,1,1],
[-37.994665,176.861951666667,1,1],
[-38.0631616666667,174.97854,1,1],
[-36.078785,177.529348333333,1,1],
[-38.9196066666667,177.873603333333,1,1],
[-35.8661633333333,174.189336666667,1,1],
[-36.3283583333333,177.802486666667,1,1],
[-37.11242,175.957198333333,1,1],
[-39.4010083333333,172.686688333333,1,1],
[-42.4813616666667,171.659536666667,1,1],
[-36.0120516666667,177.352293333333,1,1],
[-39.00966,172.821693333333,1,1],
[-41.19823,171.576271666667,1,1],
[-43.3214183333333,169.189333333333,1,1],
[-40.72748,173.928771666667,1,1],
[-36.8949783333333,175.739323333333,1,1],
[-38.6152283333333,176.332703333333,1,1],
[-43.8388466666667,169.286935,1,1],
[-40.795765,174.032096666667,1,1],
[-35.47594,175.32714,1,1],
[-35.522615,175.389836666667,1,1],
[-45.9924616666667,167.456761666667,1,1],
[-41.0157616666667,171.590661666667,1,1],
[-37.7088433333333,177.385951666667,1,1],
[-44.011005,167.381986666667,1,1],
[-39.0939316666667,175.484213333333,1,1],
[-37.2896583333333,177.063135,1,1],
[-43.5593016666667,169.25818,1,1],
[-40.8261316666667,174.117191666667,1,1],
[-38.60656,176.327905,1,1],
[-40.2043533333333,172.049511666667,1,1],
[-33.1701283333333,173.406341666667,1,1],
[-34.5565183333333,174.425721666667,1,1],
[-44.724,168.170456666667,1,1],
[-41.6539816666667,172.22665,1,1],
[-41.5950633333333,171.51886,1,1],
[-37.058015,175.14628,1,1],
[-38.2858833333333,175.126186666667,1,1],
[-39.1201933333333,175.220498333333,1,1],
[-40.7023233333333,173.572715,1,1],
[-35.516825,175.343785,1,1],
[-33.27494,173.082823333333,1,1],
[-37.7150316666667,176.496978333333,1,1],
[-34.6350916666667,174.355116666667,1,1],
[-41.8437666666667,171.791991666667,1,1],
[-33.5735683333333,172.862555,1,1],
[-35.4875083333333,175.42411,1,1],
[-45.5407983333333,169.494986666667,1,1],
[-33.5600883333333,172.715323333333,1,1],
[-34.278335,173.652603333333,1,1],
[-38.7659283333333,176.895138333333,1,1],
[-34.0638566666667,174.455745,1,1],
[-43.6483483333333,169.168591666667,1,1],
[-40.618075,174.057301666667,1,1],
[-34.3475683333333,173.555146666667,1,1],
[-43.998045,171.154305,1,1],
[-35.3943183333333,175.535488333333,1,1],
[-36.9281866666667,175.656648333333,1,1],
[-42.99659,171.588591666667,1,1],
[-45.3766283333333,169.133755,1,1],
[-44.961245,169.21398,1,1],
[-43.90194,170.831255,1,1],
[-41.5313616666667,171.187071666667,1,1],
[-34.24905,173.673725,1,1],
[-34.7706333333333,173.942123333333,1,1],
[-40.8957133333333,173.014041666667,1,1],
[-39.1584533333333,172.86749,1,1],
[-39.1667483333333,172.885035,1,1],
[-37.863175,176.239815,1,1],
[-34.7405033333333,174.126041666667,1,1],
[-35.2644033333333,175.48198,1,1],
[-34.23176,174.393618333333,1,1],
[-33.1263,173.388885,1,1],
]);
var geochart = new google.visualization.GeoChart(
document.getElementById('visualization'));
geochart.draw(data, {width: 556, height: 347});
}
This is the output:
Even if the circles are set to a small side, a bunch of circles clearly exist in both places. It seems as if the rightmost part of Russia is duplicated too.
Is there a workaround for this?
That is a consequence of the map projection used (Mercator), which ends up with areas being duplicated on the left and right sides. There is an experimental option for changing the map projection in the works now, and you can test some of it with the projection option. Currently, there are 4 projections available: 'mercator', 'albers', 'lambert', and 'kavrayskiy-vii'. Mercator and Kavrayskiy-vii are "normal" map projections, while Albers and Lambert are highly specialized projections.
The projection option is undocumented, but seems to have a structure like this:
projection: {
name: 'lambert',
parallels: [23, 56],
origin: {
lat: 45,
lng: 0
}
}
You'll have to play around with it to see what you can make work for you.
Although this is quite old now, I just faced the same issue.
My solution was to place the New Zealand marker a little bit further west using an if-statement, like so:
data.addRow([{ v:"Queenstown" , "New Zealand" }, 2 , 'Here some data' ]);
while all the other markers are placed in the countries' center:
data.addRow(["Switzerland", 2 , 'Here some data' ]);
Hope this helps!
Related
How to add horizontal line at front of the line bullet in live data amcharts
i'm working on amchart live data you can check here https://www.amcharts.com/demos/live-data/. So i want to add horizonal line at front of the line bullet like you can check here https://iqoption.com/en/ in this site when you signup and click on trade there will be chart show. at front of the line bullet there is horizontal line i want like this. So let me know is it possible ??
Amchart is a quite popular charting library, and after a few minutes of searches, it is a quite easy task to do. Based on the live-data demo provided by amchart your have to add some line to that code. To start add an axisrange line to the chart. // goal guides var axisRange = valueAxis.axisRanges.create(); axisRange.value = 4; axisRange.grid.strokeOpacity = 1; axisRange.label.text = "Goal"; // This text will be displayed on the right side of chart. axisRange.label.align = "right"; axisRange.label.verticalCenter = "bottom"; axisRange.label.fillOpacity = 0.8; After this block you will see the vertical line on the chart but this will not move along the chart In order to start to move the line you have to modify the startInterval() function From the function your have access to the previously declared axisrange variable so after getting the next value you have to assign this value to the axisrange position and label this way function startInterval() { interval = setInterval(function() { visits = visits + Math.random(); var lastdataItem = series.dataItems.getIndex(series.dataItems.length - 1); chart.addData( { date: new Date(lastdataItem.dateX.getTime() + 1000), value: visits }, 1 ); // Add this two line to the startinterval function or where you calculate the next value axisRange.value=visits; axisRange.label.text=visits; }, 1000); }
How can I scale my dataset values as a percentage of the index in chart.js?
Sorry if the question is poorly worded.Here is my chart I am looking into scaling the chart's display of dataset(s) values as a percentage such as: //input data:{ datasets[{ label: 'data1', data: [15, 22, 18, 35, 16, 29, 40] }, { label: 'data2', data: [20, 21, 20, 19, 21, 22, 35] }] data1's points on the chart would be displayed as [42.9, 51.2, 47.4, 64.8, 43.2, 56.9, 57.1] data2's points on the chart would be displayed as [57.1, 48.8, 52.6, 35.2, 56.8, 43.1, 42.9] It should look like this. All visible lines should stack up to 100%. If a dataset is hidden, how can I recalculate the percentage and update the chart so that everything stays stacked up to 100%? I thought about doing a plugin where I do the calculation using myLine.data.datasets but then I don't know how to remove a hidden dataset's values from the calculation and I'm not sure how to display it unless I overwrite the original datasets. I'm pretty sure this is the wrong approach. Any help would be greatly appreciated.
So, I figured it out. I needed to write a function to calculate the percentage area of the points in the index and then update the datasets with the calculated percentage values. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * * DS_update calculates the percentage area of the input datasets * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ function DS_update(dataset_in, ds_vis){ // make a deep copy (no references to the source) var temp = jQuery.extend(true, [], dataset_in); // gets the sum of all datasets at a given index function getTotal(index){ total = 0; // step through the datasets dataset_in.forEach(function(e, i){ // inc total if the dataset is visible if(ds_vis[i]){ total += e[index]; } // do nothing if the dataset is hidden }); return total; } // update temp array with calculated percentage values temp.forEach(function(el, ind){ var j = ind; el.forEach(function(e, i){ // calculate percentage to the hundredths place temp[j][i] = Math.round((e / getTotal(i))*10000)/100; }); }); return temp; } Once I tested the functions I had to run them before initial load of the chart or else the user would see the datasets as non area-percent (raw data). which looks something like this: // Keep source array to use in the tool tips var Src_ary = Input_data; // multidimensional array of input data // holds the percent-area calculations as datapoints var Prod_ary = DS_update(Src_ary, Init_visible(Src_ary)); Next up was updating the onClick for the legend. I need this to update the calculations every time an item's visibility is toggled: legend: { position: 'bottom', usePointStyle: true, onClick: function(e, legendItem){ var index = legendItem.datasetIndex; var ci = this.chart; var meta = ci.getDatasetMeta(index); var vis_ary = []; var updatedSet = []; // See controller.isDatasetVisible comment meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null; // load the visible array for(var i = 0; i < (ci.data.datasets || []).length; i++){ switch (ci.getDatasetMeta(i).hidden){ case null: vis_ary.push(true); break; default: vis_ary.push(false); break; } } // update datasets using vis_ary to tell us which sets are visible updatedSet = DS_update(Prod_ary, vis_ary); myLine.data.datasets.forEach(function (e,i){ e.data = updatedSet[i]; }); // We did stuff ... rerender the chart ci.update(); } } END RESULT This is what I was trying to do: highchart fiddle This is what I ended up with:fiddle It took a few days and a lot of reading through chartjs.org's documentation to put this together. In the end I think it came out pretty good considering I am new to chart.js and borderline illiterate with javascript.
Data with pair X and Y values
Is it possible to use a the pair X and Y in the data option in Chart.js to create the bar char? data: [ ['08/09/2016', 12], ['09/09/2016', 19] ], Being in the form of [X, Y] I didn't find any reference about it in the docs. The closer I got was this found in the line charts example: data: [{ x: -10, y: 0 }, { x: 0, y: 10 }, { x: 10, y: 5 }]
There is no built-in way to create your chart using an array straight into the data. But you can create a small work around using Chart.js plugins. They let you handle events triggered during the whole creation of the chart, such as before it is initialized, after a resize, etc. Follows a small plugin that will populate all the data for you using an array : var myPlugin = { // We edit what is happening before the chart is initialized. beforeInit: function(chart) { var data = chart.config.data; // `APIarray` is what you get from your API. // For every data in this array ... for (var i = 0; i < APIarray.length; i++) { // Populate the labels array with the first value .. data.labels.push(APIarray[i][0]); // .. and the data with the second value data.datasets[0].data.push(APIarray[i][1]); } } }; Then you need to add this newly created plugin to your Chart plugin services : Chart.pluginService.register(myPlugin); Make sure to register the plugin before creating the chart (before calling new Chart()), or else it won't work. I also suggest to have an empty data in your chart (before the plugin occurs) to make sure you won't have data you don't want. You can see a fully working example on this jsFiddle.
google charts, tooltip replace column value
I'm using a combo chart from the google graph api (combo chart type). I want to add custom tooltips to add information about each point in the graph, but one of the value is replaced by the tooltip. Here a very similar example graphic: adding tooltip to graphs Supposing that I'm using that graph. In my case, the value 106 (for the year 2011), is replaced by Growth 14% (the tooltip value) Here the code that generates the data: function gcomboChart () { var data = new google.visualization.DataTable(); var dataVal = [ ["January",37903,655396,3411359,"Tooltip January"], ["February",33813,559595,3035931,"Tooltip February"], ["March",54073,725638,4561690,"Tooltip March"] ]; data.addColumn('string','month'); data.addColumn('number','Value1'); data.addColumn('number','Value2'); data.addColumn('number','Value3'); data.addColumn({type:'string', role:'tooltip'}); data.addRows(dataVal); return(data); } //Here the code that generates the graph: function drawChartComboChartID14cc19be5eef() { var data = gcomboChart(); var options = { focusTarget: 'category'}; options["allowHtml"] = true; options["seriesType"] = "bars"; options["series"] = {0: {targetAxisIndex:1,type:"line"}}; options["series"] = {0: {targetAxisIndex:2,type:"line"}}; options["vAxes"] = [{title:'Left Axis',format:'#,###',titleTextStyle:{color: 'orange'},textStyle:{color: 'orange'},textPosition:'out'}, {title:'Right Axis',format:'#,###',titleTextStyle:{color: 'blue'},textStyle:{color: 'blue'},textPosition:'out'}]; options["width"] = 1000; options["height"] = 600; options["pointSize"] = 9; var chart = new google.visualization.ComboChart( document.getElementById('ComboChart')); chart.draw(data,options); } If you use the code, you'll see that the value of the third variable (Value3), is overwritten by the tooltip. I don't know hoy to get rid of that problem. I want to show the three values of 'Value1-3' plus the tooltip Can you please give me a hand? Thanks!
Tooltips by default will replace the tooltip for that data point. It will not add an additional tooltip. To get around this, you need to add an additional series, and format the tooltip manually within that data value. You can then hide it from the legend, and have it display all nice as follows: Here is the code: function gcomboChart () { var data = new google.visualization.DataTable(); //{v: x, f: y} allows you to set a manual format for each data point var dataVal = [ ["January",37903,655396,3411359,{v: 0, f:"Tooltip January"}], ["February",33813,559595,3035931,{v: 0, f:"Tooltip February"}], ["March",54073,725638,4561690,{v: 0, f:"Tooltip March"}] ]; data.addColumn('string','month'); data.addColumn('number','Value1'); data.addColumn('number','Value2'); data.addColumn('number','Value3'); // Changed to standard data rather than tooltip role data.addColumn('number',''); data.addRows(dataVal); return(data); } //Here the code that generates the graph: function drawVisualization() { var data = gcomboChart(); var options = { focusTarget: 'category'}; options["allowHtml"] = true; options["seriesType"] = "bars"; // the below line makes sure the tooltip is not shown in the legend options["series"] = {0: {targetAxisIndex:0,type:"line"},3: {visibleInLegend:false}}; options["vAxes"] = [{title:'Left Axis',format:'#,###',titleTextStyle:{color: 'orange'},textStyle:{color: 'orange'},textPosition:'out'}, {title:'Right Axis',format:'#,###',titleTextStyle:{color: 'blue'},textStyle:{color: 'blue'},textPosition:'out'}]; options["width"] = 1000; options["height"] = 600; options["pointSize"] = 9; var chart = new google.visualization.ComboChart( document.getElementById('visualization')); chart.draw(data,options); } Note: I should have switched series 3 to a line as well so that it doesn't push the bars over one. Change the series setting as follows to make it look nicer: options["series"] = {0: {targetAxisIndex:0,type:"line"},3: {visibleInLegend:false,type:"line"}};
Why is the computed property being updated even though I didn't specify its dependencies?
I have a schema structured something like this: App = {}; App.Outer = Ember.Object.extend({ inner: null, quantity: 0, count: function () { var self = this, inner = self.get('inner'); return self.get('quantity') * inner.get('count'); }.property('nothing') }); App.Inner = Ember.Object.extend({ count: 0 }); Yes, the 'count' computed property really is set to depend on a totally nonexistent property 'nothing'. However it seems to get updated anyway: var o1 = App.Outer.create({ quantity: 2, inner: App.Inner.create({count: 4}) }); console.log(o1.get('count')); // => 8 o1.get('inner').set('count', 5); console.log(o1.get('count')); // => 10 o1.set('inner', App.Inner.create({count: 10})); console.log(o1.get('count')); // => 20 Am I missing something? It knows what to update without me telling it what to depend on... can't be right, can it? What am I misunderstanding about Ember computed properties? Thanks
By using this.get('quantity'), inner.get('count') you are telling it what it depends on. Every time you call .get('count') the function will go off and get the current values for those properties and therefore return the up to date result. The .property() part comes into play when you bind the computed property count to something else e.g. a view. When you do that then making a change to quantity will automatically recalculate the count, and this new value will be propagated to whatever you have bound the count too. You can see the difference in action here: http://jsfiddle.net/tomwhatmore/6gz8x/
As of Ember 0.9.5, property values are not cached unless cacheable() is called on them. e.g. ... count: function () { var self = this, inner = self.get('inner'); return self.get('quantity') * inner.get('count'); }.property('nothing').cacheable() ... For more background, see the discussion on this GitHub issue: https://github.com/emberjs/ember.js/issues/38