Generating Different Colours On the JVectorMap Regions Based On The Range Of Values - jvectormap

I'm using JVectorMap for creating World Map..
As part of my JVectorMap im displaying on the regions CountryName with Population..
My Question is:
How to show differrent colours for the regions (countries) based on population ranges.
Ex: For 1-1000 population i have to show red colour.
For 1000-5000 population i have to show blue colour.
I'm using code like this.But it is not displaying different colours based on the range of population
var mapData = {
"AF": 1000,
"AL": 5000,
"DZ": 20000,
...
};
try{
$('#id').vectorMap(
{
map : 'world_mill_en',
series : {
regions : [ {
initial : {
fill : 'white',
"fill-opacity" : 1,
stroke : 'none',
"stroke-width" : 0,
"stroke-opacity" : 1
},
hover : {
"fill-opacity" : 0.8
},
selected : {
fill : 'yellow'
},
selectedHover : {},
values : mapData,
scale : [ '#C8EEFF', '#0071A4' ],
normalizeFunction : 'polynomial'
} ]
},
onRegionLabelShow : function(e, el, code) {
el.html(el.html()+' (Population - '+mapData[code]+')');
}
});
}
catch(err){
alert(err);
}
Can any one help me in displaying differnt colours for the regions based on the range of population......?
Thanks in advance..

Create a JSON with count and color codes like this according to your regions and colors.
var colorData = {
"1" : "#C8EEFF",
"2" : "#0071A4",
"3" : "#C8EEFF",
"4" : "#0071A4",
"5" : "#C8EEFF",
"6" : "#0071A4"
}
and pass this JSON to the scale : colorData. Hope it helps you.

Related

Highlight Major Value Grid Lines

Is there a setting that I'm missing to highlight major axis grid lines? I've mocked up an example of what I'm trying to do below. The arrows point to what I want, the circle shows what I have. The axis value highlights the day of the week, but not the grid line. I have a feeling that it is considering the 12 pm's as major axis grid lines too.
Here is what I have for the categoryAxis:
"categoryAxis" :
{
"equalSpacing" : true,
"minPeriod" : "hh",
"parseDates" : true,
"fontSize" : 24,
"dateFormats" : [
{
period : 'fff',
format : 'JJ:NN:SS'
},
{
period : 'ss',
format : 'JJ:NN:SS'
},
{
period : 'mm',
format : 'JJ:NN'
},
{
period : 'hh',
format : 'L A'
},
{
period : 'DD',
format : 'MMM DD\n L A'
},
{
period : 'WW',
format : 'MMM DD\n L A'
},
{
period : 'MM',
format : 'MMM DD\n L A'
},
{
period : 'YYYY',
format : 'MMM DD\n L A'
}]
},
No, there isn't a setting that highlights those lines automatically. You can use a guide to highlight those times by drawing a darker line.
Typically, this is done manually, however you can use the init event to automatically do this by having it read the category axis' internal start and end dates and placing the guides as needed:
var chart = AmCharts.makeChart("chartdiv", {
// ...
"listeners": [{
"event": "init",
"method": function(e) {
//get the start and end date objects from the categoryAxis' internal data array
var startDate = new Date(e.chart.categoryAxis.data[0].category);
var endDate = new Date(e.chart.categoryAxis.data[e.chart.categoryAxis.data.length - 1].category);
var guides = [];
var guideDate;
//start at midnight
startDate.setHours(0, 0, 0, 0);
while (startDate.getTime() <= endDate.getTime()) {
guideDate = new Date(startDate);
guides.push({
"lineAlpha": 1,
"lineColor": "#000",
"date": guideDate
});
startDate.setDate(startDate.getDate() + 1);
}
//remove the first guide if it falls outside of the full date range of the axis
if (guides[0].date.getTime() < e.chart.categoryAxis.data[0].category.getTime()) {
guides.shift();
}
e.chart.categoryAxis.guides = guides;
e.chart.validateNow(); //draw the guides
}
}]
});
Demo

Formatting currency when exporting amCharts

I'm working with amCharts 3.20.9, I sucesfully draw a graph and may export the data into an XLSX file. However, one of the columns I'm exporting is a currency, is there a way of setting such a format in the resulting file?
The script I have for the graph is:
var chart = AmCharts.makeChart("graph", {
"type" : "serial",
"theme" : "light",
"dataProvider" : data,
"valueAxes" : [ {
"stackType": "regular",
"gridColor" : "#FFFFFF",
"gridAlpha" : 0.2,
"dashLength" : 0,
"title" : "Metros cúbicos"
} ],
"gridAboveGraphs" : true,
"startDuration" : 1,
"graphs" : graphs,
"chartCursor" : {
"categoryBalloonEnabled" : false,
"cursorAlpha" : 0,
"zoomable" : false
},
"categoryField" : "formatedTime",
"categoryAxis" : {
"gridPosition" : "start",
"gridAlpha" : 0,
"tickPosition" : "start",
"tickLength" : 20,
"parseDates" : false,
"labelsEnabled": true,
"labelFrequency": 3
},
"export" : {
"enabled" : true,
"fileName" : "Reporte",
"exportTitles" : true,
"exportFields" : fields,
"columnNames" : columnNames,
"menu" : [ {
"class" : "export-main",
"menu" : [ "PDF", "XLSX" ]
} ]
}
});
Where:
graphs contains the graphs definitions, something like:
[{
"balloonText" : "[[formatedTime]]: <b>[[" + sites[i] + "]]</b>",
"balloonFunction" : formater,
"lineThickness": 1,
"lineAlpha" : 0.2,
"type" : "line",
"valueField" : sites[i]
}];
fields: ["formatedTime", "Viva Villavicencio", "Viva Villavicencio_COST_"]
columnNames: {"formatedTime": "Fecha", "Viva Villavicencio": "Metros cúbicos para: Viva Villavicencio", "Viva Villavicencio_COST_": "Costo para: Viva Villavicencio"}
So far so good, I have my xlsx with the proper data, but at the end I want the column "Viva Villavicencio_COST_" be defined as a currency in the resulting file and therefore formatted and displayed that way.
Any help will be appreciated.
Have a look at the processData option. It takes a callback function that lets you make changes to your dataset before it gets written to your exported file.
So, add to your code:
"export": {
"processData": function(data){
for(var i = 0; i < data.length; i++){
data[i].Viva Villavicencio_COST_ = toCurrency(data[i].Viva Villavicencio_COST_);
}
return data;
}
...
}
This function returns the exact dataset as before, but with a formatted Viva Villavicencio_COST_ field.
Then, add the function toCurrency. I don't believe amCharts has a function built in for formatting. If you need a better formatting function you could use something like numeral.js or accounting.js, but for now try:
function toCurrency(value){
return '$' + value;
}
Complete docs for the export plugin are here: https://github.com/amcharts/export
Hope that helps.

Specifying "groups" dynamically in stacked bar chart c3js

//take this code as an example
Here i have specified yvalue[0],yvalue[1] in groups..
But i need a general design ,where I dont know the number of groups that i have to create(i.e the number of segments) this varies according to the json data.
Consider this example here I have total,total1 therefore i have only 2 values.But if a third variable say total2 is specified in json, I should have a segment for it in my bar chart and so on.This has to be done without altering the groups everytime a field is added.Is there any way to achieve this??
Thanks
var datajson = [ {
country : "china",
total : 20,
total1 : 10
}, {
country : "India",
total : 40,
total1 : 20
}, {
country : "aus",
total : 10,
total1 : 30
}, {
country : "nxz",
total : 50,
total1 : 40
}
];
var xvalue;
var yvalue = [];
var i = 0;
var obj = datajson[0]
for ( var key in obj) {
if (xvalue === undefined)
xvalue = key;
else {
yvalue[i] = key;
i++;
}
}
var chart = c3.generate({
bindto : '#chart',
data : {
json : datajson,
type : 'bar',
keys : {
x : xvalue, // it's possible to specify 'x' when category axis
value : [yvalue[0],yvalue[1]],
},
groups : [ [yvalue[0],yvalue[1]] ]
},
bar : {
width : {
ratio : 0.3
// this makes bar width 50% of length between ticks
}
},
axis : {
x : {
type : 'category'
},
}
});
Your question seems to have most of the answer (you are already generating the yvalue array from the object properties).
You just don't have to specify the elements one by one, instead you can just pass in the array directly and you are done.
groups: [yvalue]

MongoDB Data Model Optimization

About
I have raw data which is processed by aggregation framework and later results saved in another collection. Let's assume aggregation results in something like this:
cursor = {
"result" : [
{
"_id" : {
"x" : 1,
"version" : [
"2_0"
],
"date" : {
"year" : 2015,
"month" : 3,
"day" : 26
}
},
"x" : 1,
"count" : 2
}
],
"ok" : 1
};
Note that in most cases cursor length are more than about 2k elements.
So, now i'm looping thought cursor ( cursor.forEach ) and performing following steps:
// Try to increment values:
var inc = db.runCommand({
findAndModify: my_coll,
query : {
"_id.x" : "1",
"value.2_0" : {
"$elemMatch" : {
"date" : ISODate("2015-12-18T00:00:00Z")
}
}
},
update : { $inc: {
"value.2_0.$.x" : 1
} }
});
// If there's no effected row via inc operation, - sub-element doesn't exists at all
// so let's push it
if (inc.value == null) {
date[date.key] = date.value;
var up = db.getCollection(my_coll).update(
{
"_id.x" : 1
},
{
$push : {}
},
{ writeConcern: { w: "majority", wtimeout: 5000 } }
);
// No document found for inserting sub element, let's create it
if (up.nMatched == 0) {
db.getCollection(my_coll).insert({
"_id" : {
"x" : 1
},
"value" : {}
});
}}
Resulting data-structure:
data = {
"_id" : {
"x" : 1,
"y" : 1
},
"value" : {
"2_0" : [
{
"date" : ISODate("2014-12-17T00:00:00.000Z"),
"x" : 1
},
{
"date" : ISODate("2014-12-18T00:00:00.000Z"),
"x" : 2
}
]
}
};
In short i have to apply these actions to process my data:
Try to increment values.
If there's no effected data by increment operation push data to array.
If there's no effected data by push operation create new document.
Problem:
In some cases aggregation result returns more than 2k results i have to apply mentioned steps who causes performance bottleneck. While i'm processing already aggregated data, - new data accumulates for aggregation and later i cannot apply even aggregation to this new raw data because it exceeds 64MB size limit due firsts slowness.
Question:
How i can with this data-structure improve performance when increasing x ( see data-stucture ) values or adding-sub elements?
Also i cannot apply mongodb bulk operations due nested structure using positional parameter.
Maybe chosen data-model is not correct? Or maybe i'm doing not correctly aggregation task at all?
How i can improve aggregated data insertions?

Force ticks to be whole numbers

Exactly the same as this question, but since I don't have the reputation to upvote it (and can't answer it), I'm going to have to ask it again...
Given a graph like the following, how can I force the ticks to always be whole numbers, even if the graph is empty? At the moment, if there is no data for the graph, it will go 0, 0.2, 0.4, 0.6, 0.8, 1.0, but in the context of this graph, that makes no sense - what is being displayed can only consist of whole numbers. If the numbers involved are very small, it can occasionally display as, e.g., 1.0, 1.5, 2.0, 2.5, 3.0, 3.5 (etc), which again is not ideal. As the graph represents things that have happened over the course of the day, it will start out at zero each day and slowly grow, resetting to zero the next day. Ideally, I would like the ticks to start out at 0, 1, 2, 3, 4, 5, and then scale appropriately with the data.
Any suggestions? I've tried tickInterval: 1 (and 5 and 50...) in both the X and Y axes, but that didn't seem to do anything... Maybe a bug in JQPlot?
EDIT: JSFiddle Example showing the problem.
$.jqplot('chartdiv', [ data.a, data.b ], {
title : "Title",
stackSeries : true,
seriesDefaults : {
renderer : $.jqplot.BarRenderer,
rendererOptions : {
barMargin : 15,
barDirection : 'horizontal'
},
pointLabels : {
show : true,
stackedValue : false
},
},
seriesColors : [ "#651811", "#126542" ],
axesDefaults : {
tickRenderer : $.jqplot.CanvasAxisTickRenderer,
tickOptions : {
fontSize : '8pt'
}
},
axes : {
xaxis : {
label : "X-Label",
},
yaxis : {
renderer : $.jqplot.CategoryAxisRenderer,
ticks : [ "T1", "T2", "T3", "T4" ],
tickOptions : {
angle : -75
},
label : "Y-Label",
labelRenderer : $.jqplot.CanvasAxisLabelRenderer,
labelOptions : {
angle : -90
},
}
},
highlighter : {
show : false,
showTooltip : false,
},
legend : {
show : true,
location : 'e',
placement : 'outside',
labels : [ 'L1', 'L2' ]
}
});
You might have better luck setting the max and min values for the axis, then let JQPlot fill in the tick values.
// This is YOUR data set
var series = [882, 38, 66, 522, 123, 400, 777];
var max;
if (series.length > 0) {
// Instead of letting JQPlot pick the scale on the y-axis, let's figure out our own.
var series_max = Math.max.apply(null, series);
var digits = max.toString().length;
var scale = Math.pow(10, max_digits - 1);
max = (Math.ceil(series_max / scale)) * scale;
} else {
// Since you sometimes have an empty dataset, then just pick an arbitrary max.
max = 10;
}
$.jqplot(
'foo',
[series],
{
axes: {
yaxis: {
min: 0,
max: max
}
}
// Put your other config stuff here
}
)
This basic approach works for any integers. If you are using floats and they are greater than 1, you can still use this approach by casting your "series_max" to int. If you are using floats less than 1, this approach may not be suitable: it will always pick 1 as the y-axis max.

Resources