Detecting when a schedule item has moved with AlloyUI Scheduler - scheduler

I'm new to using the AlloyUI Scheduler. I have found how to display an alert if a item is saved, edited or deleted but I can't seem to find out how to show an alert if the item is moved, ie moved to another time or day. I would have thought that the 'edit' event would have handled this but apparently not. This is the code I have.
var eventRecorder = new Y.SchedulerEventRecorder({
on: {
save: function (event) {
alert('Save Event:');
},
edit: function (event) {
alert('Edit Event:');
},
delete: function (event) {
alert('Delete Event:');
}
}
});
var schedule = new Y.Scheduler(
{
boundingBox: '#myScheduler',
date: new Date(2018, 7, 25),
eventRecorder: eventRecorder,
items: events,
render: true,
views: [dayView, weekView, monthView, agendaView]
}
);
I did try :-
Moved: function (event) {alert('Moved');}
But it didn't work

For each view you'll need to listen to the after drag:end event for each view. Unfortunately, this event doesn't provide the dragged SchedulerEvent, so you'll need to obtain it in an appropriate way for each view:
function afterEventMoved(event, scheduler) {
var startDate;
var endDate;
// Obtain the new start and end dates in the month view.
if (event.currentTarget.originalDragNode) {
var eventNodeId = event.currentTarget.originalDragNode.get('id');
var eventsArray = scheduler.getEvents();
var movedEvent = null;
for (var i = 0; i < eventsArray.length; i++) {
if (eventNodeId === eventsArray[i].get('node').get('id')[0]) {
movedEvent = eventsArray[i];
break;
}
}
startDate = movedEvent.get('startDate');
endDate = movedEvent.get('endDate');
}
// Obtain the new start and end dates in the day and week views.
// Unfortunately, there seems to be a bug and the time of these dates
// seems to be incorrect (it seems to be the time before the event was dragged).
// The day, month, and year seem to be correct though.
else {
startDate = event.currentTarget.draggingEventStartDate;
endDate = event.currentTarget.draggingEventEndDate;
}
console.log(startDate);
console.log(endDate);
}
Just use a function like the one above during the after drag:end event for each view and you'll be able to obtain the new start and end dates of the dragged event.
YUI().use('aui-scheduler', function (Y) {
var scheduler = null;
var viewConfig = {
after: {
'drag:end': function(event) {
afterEventMoved(event, scheduler);
}
}
};
var agendaView = new Y.SchedulerAgendaView();
var dayView = new Y.SchedulerDayView(viewConfig);
var monthView = new Y.SchedulerMonthView(viewConfig);
var weekView = new Y.SchedulerWeekView(viewConfig);
var eventRecorder = new Y.SchedulerEventRecorder();
var events = [ /* ...your events here... */ ];
scheduler = new Y.Scheduler({
activeView: monthView,
boundingBox: '#myScheduler',
date: new Date(2013, 1, 4),
eventRecorder: eventRecorder,
items: events,
render: true,
views: [dayView, weekView, monthView, agendaView]
});
});
Runnable example:
<script src="https://cdn.alloyui.com/3.0.1/aui/aui-min.js"></script>
<link href="https://cdn.alloyui.com/3.0.1/aui-css/css/bootstrap.min.css" rel="stylesheet"></link>
<script type="text/javascript">
function afterEventMoved(event, scheduler) {
var startDate;
var endDate;
if (event.currentTarget.originalDragNode) {
var eventNodeId = event.currentTarget.originalDragNode.get('id');
var eventsArray = scheduler.getEvents();
var movedEvent = null;
for (var i = 0; i < eventsArray.length; i++) {
if (eventNodeId === eventsArray[i].get('node').get('id')[0]) {
movedEvent = eventsArray[i];
break;
}
}
startDate = movedEvent.get('startDate');
endDate = movedEvent.get('endDate');
}
else {
startDate = event.currentTarget.draggingEventStartDate;
endDate = event.currentTarget.draggingEventEndDate;
}
console.log(startDate);
console.log(endDate);
}
YUI().use('aui-scheduler', function (Y) {
var scheduler = null;
var viewConfig = {
after: {
'drag:end': function(event) {
afterEventMoved(event, scheduler);
}
}
};
var agendaView = new Y.SchedulerAgendaView();
var dayView = new Y.SchedulerDayView(viewConfig);
var monthView = new Y.SchedulerMonthView(viewConfig);
var weekView = new Y.SchedulerWeekView(viewConfig);
var eventRecorder = new Y.SchedulerEventRecorder();
var events = [{
content: 'AllDay',
endDate: new Date(2013, 1, 5, 23, 59),
startDate: new Date(2013, 1, 5, 0)
},
{
color: '#8D8',
content: 'Colorful',
endDate: new Date(2013, 1, 6, 6),
startDate: new Date(2013, 1, 6, 2)
},
{
content: 'MultipleDays',
endDate: new Date(2013, 1, 8),
startDate: new Date(2013, 1, 4)
},
{
content: 'Disabled',
disabled: true,
endDate: new Date(2013, 1, 8, 5),
startDate: new Date(2013, 1, 8, 1)
},
{
content: 'Meeting',
endDate: new Date(2013, 1, 7, 7),
meeting: true,
startDate: new Date(2013, 1, 7, 3)
},
{
color: '#88D',
content: 'Overlap',
endDate: new Date(2013, 1, 5, 4),
startDate: new Date(2013, 1, 5, 1)
},
{
content: 'Reminder',
endDate: new Date(2013, 1, 4, 4),
reminder: true,
startDate: new Date(2013, 1, 4, 0)
}
];
scheduler = new Y.Scheduler({
activeView: monthView,
boundingBox: '#myScheduler',
date: new Date(2013, 1, 4),
eventRecorder: eventRecorder,
items: events,
render: true,
views: [dayView, weekView, monthView, agendaView]
});
});
</script>

Related

Google Bar Chart - custom Legend text with total values & column wise total for Table chart

i would like get the total value of Grades in Stacked Bar Graph Legend. picture attached how i wud like to have... for the following working snippet.
and also the Column wise Total for the Table Chart...
i think this can be done with following but how to get it done..
data.setFormattedValue(i, 0, key + ' (' + val + ')');
can have something like this.. when mouseover one location on Bar... need to show all the grades values in single annotation..??
is it possible to have the different values in highlighted places like in below picture? circle B is overall total of Grade1 in graph is correct. and circle A the tooltip total should show for that particular locations total of every Grade's annotation like below.
['Location', 'Company', 'Grade1',{ role: 'annotation' }, 'Grade2',{ role: 'annotation' }, 'Grade3',{ role: 'annotation' }, 'Bal-Grade', 'Total', { role: 'annotation' } ],
google.charts.load('current', {
packages: ['corechart', 'table', 'gauge', 'controls']
}).then(function () {
drawMainDashboard();
});
function drawMainDashboard() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_division1'));
var categoryPicker = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'categoryPicker_div',
'options': {
'filterColumnIndex': 1,
'ui': {
'labelStacking': 'vertical',
'label': 'Company Selection:',
'allowTyping': false,
'allowMultiple': false
}
}
});
var categoryPicker1 = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'categoryPicker_div1',
'options': {
'filterColumnIndex': 0,
'ui': {
'labelStacking': 'vertical',
'label': 'Location Selection:',
'allowTyping': false,
'allowMultiple': false
}
}
});
var columnchrt = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'chart_div',
'options': {
title: "Locations charts",
width: 850,
height: 500,
legend: { position: 'top', maxLines: 2 },
bar: { groupWidth: '70%' },
isStacked: true,
focusTarget: 'category',
aggregationTarget: 'category',
explorer: {keepInBounds: true, maxZoomIn: 10.0}
}
});
var table = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'table_div',
'options': {
showRowNumber: true,
width: '100%',
height: '100%',
allowHtml: true
},
'view': {'columns': [0,1,2,3,4,5,6]}
});
google.visualization.events.addOneTimeListener(table, 'ready', calcTotals);
function calcTotals() {
// get filtered data table from table chart
var dt = table.getDataTable();
// build aggregation and view columns
var aggColumns = [];
var viewColumns = [0];
for (var i = 2; i < dt.getNumberOfColumns(); i++) {
if (i !== dt.getNumberOfColumns() - 1) {
if (dt.getColumnType(i) === 'number') {
if (dt.getColumnRole(i) !== 'annotation') {
addAggColumn(i);
if (i !== dt.getNumberOfColumns() - 2) {
viewColumns.push(i - 1);
}
}
}
}
}
function addAggColumn(index) {
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index,
label: dt.getColumnLabel(index),
type: dt.getColumnType(index)
});
}
// aggregate data table
var agg = google.visualization.data.group(
dt,
[0],
aggColumns
);
var aggTotal = google.visualization.data.group(
dt,
[{
column: 0,
label: 'Total',
modifier: function (val) {
return 'Total';
},
type: 'string'
}],
aggColumns
);
dt = dt.toDataTable();
dt.addRow(['Total', '--', aggTotal.getValue(0, 1), aggTotal.getValue(0, 2), aggTotal.getValue(0, 3), aggTotal.getValue(0, 4), aggTotal.getValue(0, 5), null]);
table.setDataTable(dt);
table.draw();
viewColumns.push({
calc: function (dt, row) {
var total = 0;
for (var c = 1; c < dt.getNumberOfColumns(); c++) {
if (dt.getColumnLabel(c) !== 'Total') {
total += dt.getValue(row, c);
}
}
return total.toFixed(0);
},
role: 'annotation',
type: 'string'
});
// create agg data view to add annotation
var view = new google.visualization.DataView(agg);
view.setColumns(viewColumns);
view = view.toDataTable();
for (var vc = 0; vc < view.getNumberOfColumns(); vc++) {
var viewLabel = view.getColumnLabel(vc);
for (var ac = 0; ac < agg.getNumberOfColumns(); ac++) {
var aggLabel = agg.getColumnLabel(ac);
if (viewLabel === aggLabel) {
view.setColumnLabel(vc, viewLabel + ' (' + aggTotal.getFormattedValue(0, ac) + ')');
}
}
}
// draw chart
columnchrt.setDataTable(view);
columnchrt.draw();
google.visualization.events.addOneTimeListener(table, 'ready', calcTotals);
}
var data = google.visualization.arrayToDataTable([
['Location', 'Company', 'Grade1', 'Grade2', 'Grade3', 'Bal-Grade', 'Total', { role: 'annotation' } ],
['NYC', 'CUSTOMERS', 0, 0, 13, 5, 19, 29],
['CALI', 'ORG', 270, 210, 0, 32, 51, 60],
['CALI', 'CUSTOMERS', 35.942, 39, 0, 50, 126, 150],
['WDC', 'CUSTOMERS', 0, 0, 35, 52, 88, 100],
['WDC', 'CUSTOMERS', 44.507, 0, 25, 18, 88, 110],
['NJ', 'ORG', 0, 0, 54, 22, 28, 45],
['TXS', 'CUSTOMERS', 0, 0, 0, 10, 11, 20]
]);
dashboard.bind([categoryPicker,categoryPicker1], [table]);
dashboard.draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_division" style="clear:left; display:inline-block; width:100%; float:left; margin-top:5px;">
<div class="float_left panel" style="float:left; width:50%; padding:0px;">
<div id="chart_div"></div>
</div>
<div class="float_left panel" style="width:50%; padding:0px;">
<div class="table_bbar" style="background-color:#27ae60;" >
<div id="categoryPicker_div" style="right:15px; position:absolute;"></div>
<div id="categoryPicker_div1" ></div>
</div>
<div id="table_div"></div>
</div>
</div>
to get the total row for the table chart,
we can use a modifier function in the aggregation.
we aggregate once by location,
then again in total.
the modifier function allows us to return the same value for every row,
thus giving us the total for all rows.
then we can add the results from the total agg to the location agg.
// aggregate data table
var agg = google.visualization.data.group(
dt,
[0],
aggColumns
);
var aggTotal = google.visualization.data.group(
dt,
[{
column: 0,
label: 'Total',
modifier: function (val) {
return 'Total';
},
type: 'string'
}],
aggColumns
);
var rowIndex = agg.addRow();
for (var i = 0; i < agg.getNumberOfColumns(); i++) {
agg.setValue(rowIndex, i, aggTotal.getValue(0, i));
}
then we can use the agg total data table to set the labels in the column chart legend.
// create agg data view to add annotation
var view = new google.visualization.DataView(agg);
view.setColumns(viewColumns);
view = view.toDataTable();
for (var vc = 0; vc < view.getNumberOfColumns(); vc++) {
var viewLabel = view.getColumnLabel(vc);
for (var ac = 0; ac < agg.getNumberOfColumns(); ac++) {
var aggLabel = agg.getColumnLabel(ac);
if (viewLabel === aggLabel) {
view.setColumnLabel(vc, viewLabel + ' (' + aggTotal.getFormattedValue(0, ac) + ')');
}
}
}
one other slight change, since we are re-drawing the charts inside the 'ready' event,
we must use a one time event, else we'll go into an endless loop.
google.visualization.events.addOneTimeListener(table, 'ready', calcTotals);
see following working snippet...
google.charts.load('current', {
packages: ['corechart', 'table', 'gauge', 'controls']
}).then(function () {
drawMainDashboard();
});
function drawMainDashboard() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_division1'));
var categoryPicker = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'categoryPicker_div',
'options': {
'filterColumnIndex': 1,
'ui': {
'labelStacking': 'vertical',
'label': 'Company Selection:',
'allowTyping': false,
'allowMultiple': false
}
}
});
var categoryPicker1 = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'categoryPicker_div1',
'options': {
'filterColumnIndex': 0,
'ui': {
'labelStacking': 'vertical',
'label': 'Location Selection:',
'allowTyping': false,
'allowMultiple': false
}
}
});
var columnchrt = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'chart_div',
'options': {
title: "Locations charts",
width: 850,
height: 500,
legend: { position: 'top', maxLines: 2 },
bar: { groupWidth: '70%' },
isStacked: true,
explorer: {keepInBounds: true, maxZoomIn: 10.0}
}
});
var table = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'table_div',
'options': {
showRowNumber: true,
width: '100%',
height: '100%',
allowHtml: true
},
'view': {'columns': [0,1,2,3,4,5,6]}
});
google.visualization.events.addOneTimeListener(table, 'ready', calcTotals);
function calcTotals() {
// get filtered data table from table chart
var dt = table.getDataTable();
// build aggregation and view columns
var aggColumns = [];
var viewColumns = [0];
for (var i = 2; i < dt.getNumberOfColumns(); i++) {
if (i !== dt.getNumberOfColumns() - 1) {
if (dt.getColumnType(i) === 'number') {
if (dt.getColumnRole(i) !== 'annotation') {
addAggColumn(i);
if (i !== dt.getNumberOfColumns() - 2) {
viewColumns.push(i - 1);
}
}
}
}
}
function addAggColumn(index) {
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index,
label: dt.getColumnLabel(index),
type: dt.getColumnType(index)
});
}
// aggregate data table
var agg = google.visualization.data.group(
dt,
[0],
aggColumns
);
var aggTotal = google.visualization.data.group(
dt,
[{
column: 0,
label: 'Total',
modifier: function (val) {
return 'Total';
},
type: 'string'
}],
aggColumns
);
dt = dt.toDataTable();
dt.addRow(['Total', '--', aggTotal.getValue(0, 1), aggTotal.getValue(0, 2), aggTotal.getValue(0, 3), aggTotal.getValue(0, 4), aggTotal.getValue(0, 5), null]);
table.setDataTable(dt);
table.draw();
viewColumns.push({
calc: function (dt, row) {
var total = 0;
for (var c = 1; c < dt.getNumberOfColumns(); c++) {
if (dt.getColumnLabel(c) !== 'Total') {
total += dt.getValue(row, c);
}
}
return total.toFixed(0);
},
role: 'annotation',
type: 'string'
});
// create agg data view to add annotation
var view = new google.visualization.DataView(agg);
view.setColumns(viewColumns);
view = view.toDataTable();
for (var vc = 0; vc < view.getNumberOfColumns(); vc++) {
var viewLabel = view.getColumnLabel(vc);
for (var ac = 0; ac < agg.getNumberOfColumns(); ac++) {
var aggLabel = agg.getColumnLabel(ac);
if (viewLabel === aggLabel) {
view.setColumnLabel(vc, viewLabel + ' (' + aggTotal.getFormattedValue(0, ac) + ')');
}
}
}
// draw chart
columnchrt.setDataTable(view);
columnchrt.draw();
google.visualization.events.addOneTimeListener(table, 'ready', calcTotals);
}
var data = google.visualization.arrayToDataTable([
['Location', 'Company', 'Grade1', 'Grade2', 'Grade3', 'Bal-Grade', 'Total', { role: 'annotation' } ],
['NYC', 'CUSTOMERS', 0, 0, 13, 5, 19, 19],
['CALI', 'ORG', 270, 210, 0, 32, 51, 51],
['CALI', 'CUSTOMERS', 35.942, 39, 0, 50, 126, 126],
['WDC', 'CUSTOMERS', 0, 0, 35, 52, 88, 88],
['WDC', 'CUSTOMERS', 44.507, 0, 25, 18, 88, 88],
['NJ', 'ORG', 0, 0, 54, 22, 28, 28],
['TXS', 'CUSTOMERS', 0, 0, 0, 10, 11, 11]
]);
dashboard.bind([categoryPicker,categoryPicker1], [table]);
dashboard.draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_division" style="clear:left; display:inline-block; width:100%; float:left; margin-top:5px;">
<div class="float_left panel" style="float:left; width:50%; padding:0px;">
<div id="chart_div"></div>
</div>
<div class="float_left panel" style="width:50%; padding:0px;">
<div class="table_bbar" style="background-color:#27ae60;" >
<div id="categoryPicker_div" style="right:15px; position:absolute;"></div>
<div id="categoryPicker_div1" ></div>
</div>
<div id="table_div"></div>
</div>
</div>

Highmaps mappies with drilldown

I need to do a drilldown of mappies, from country to states:
https://www.highcharts.com/maps/demo/map-pies
Actually I am using a custom map from Peru, but already with the example of USA would help me a lot showing me some solution.
Is it possible to do this?
I've made an example with mappie and drilldown to show you how to start and achieve it. I've added drilldown for California so only this state will work.
Add drilldown module: https://code.highcharts.com/maps/modules/drilldown.js
Each point should have a drilldown property set. You can add it to a point object or to data array (then keys array in series should point to it. API: https://api.highcharts.com/highmaps/plotOptions.series.keys)
When drilldown event occurs hide or remove each mappie series and create it again on drillup event.
Code:
// New map-pie series type that also allows lat/lon as center option.
// Also adds a sizeFormatter option to the series, to allow dynamic sizing
// of the pies.
Highcharts.seriesType('mappie', 'pie', {
center: null, // Can't be array by default anymore
clip: true, // For map navigation
states: {
hover: {
halo: {
size: 5
}
}
},
dataLabels: {
enabled: false
}
}, {
getCenter: function() {
var options = this.options,
chart = this.chart,
slicingRoom = 2 * (options.slicedOffset || 0);
if (!options.center) {
options.center = [null, null]; // Do the default here instead
}
// Handle lat/lon support
if (options.center.lat !== undefined) {
var point = chart.fromLatLonToPoint(options.center);
options.center = [
chart.xAxis[0].toPixels(point.x, true),
chart.yAxis[0].toPixels(point.y, true)
];
}
// Handle dynamic size
if (options.sizeFormatter) {
options.size = options.sizeFormatter.call(this);
}
// Call parent function
var result = Highcharts.seriesTypes.pie.prototype.getCenter.call(this);
// Must correct for slicing room to get exact pixel pos
result[0] -= slicingRoom;
result[1] -= slicingRoom;
return result;
},
translate: function(p) {
this.options.center = this.userOptions.center;
this.center = this.getCenter();
return Highcharts.seriesTypes.pie.prototype.translate.call(this, p);
}
});
var data = [
// state, demVotes, repVotes, libVotes, grnVotes, sumVotes, winner, offset config for pies
['Alabama', 729547, 1318255, 44467, 9391, 2101660, -1],
['Alaska', 116454, 163387, 18725, 5735, 304301, -1],
['Arizona', 1161167, 1252401, 106327, 34345, 2554240, -1],
['Arkansas', 380494, 684782, 29829, 9473, 1104578, -1],
['California', 8577206, 4390272, 467370, 271047, 13705895, 1, {
lon: -1,
drawConnector: false
}, 'us-ca'],
['Colorado', 1338870, 1202484, 144121, 38437, 2723912, 1],
['Connecticut', 897572, 673215, 48676, 22841, 1642304, 1, {
lat: -1.5,
lon: 1
}],
['Delaware', 235603, 185127, 14757, 6103, 441590, 1, {
lat: -1.3,
lon: 2
}],
['District of Columbia', 282830, 12723, 4906, 4258, 304717, 1, {
lat: -2,
lon: 2
}],
['Florida', 4504975, 4617886, 207043, 64399, 9394303, -1],
['Georgia', 1877963, 2089104, 125306, 0, 4092373, -1],
['Hawaii', 266891, 128847, 15954, 12737, 424429, 1, {
lat: -0.5,
lon: 0.5,
drawConnector: false
}],
['Idaho', 189765, 409055, 28331, 8496, 635647, -1],
['Illinois', 2977498, 2118179, 208682, 74112, 5378471, 1],
['Indiana', 1039126, 1557286, 133993, 7841, 2738246, -1],
['Iowa', 653669, 800983, 59186, 11479, 1525317, -1],
['Kansas', 427005, 671018, 55406, 23506, 1176935, -1],
['Kentucky', 628854, 1202971, 53752, 13913, 1899490, -1],
['Louisiana', 780154, 1178638, 37978, 14031, 2010801, -1],
['Maine', 352156, 332418, 37578, 13995, 736147, 1],
['Maryland', 1502820, 878615, 78225, 33380, 2493040, 1, {
lon: 0.6,
drawConnector: false
}],
['Massachusetts', 1995196, 1090893, 138018, 47661, 3271768, 1, {
lon: 3
}],
['Michigan', 2268839, 2279543, 172136, 51463, 4771981, -1],
['Minnesota', 1367716, 1322951, 112972, 36985, 2840624, 1, {
lon: -1,
drawConnector: false
}],
['Mississippi', 462127, 678284, 14411, 3595, 1158417, -1],
['Missouri', 1054889, 1585753, 96404, 25086, 2762132, -1],
['Montana', 174281, 273879, 28036, 7868, 484064, -1],
['Nebraska', 273185, 485372, 38746, 8337, 805640, -1],
['Nevada', 539260, 512058, 37384, 0, 1088702, 1],
['New Hampshire', 348526, 345790, 30694, 6465, 731475, 1],
['New Jersey', 1967444, 1509688, 72143, 37131, 3586406, 1, {
lat: -1,
lon: 1.2
}],
['New Mexico', 380923, 316134, 74544, 9797, 781398, 1],
['New York', 4145376, 2638135, 162273, 100110, 7045894, 1],
['North Carolina', 2169496, 2345235, 130021, 1038, 4645790, -1],
['North Dakota', 93758, 216794, 21434, 378, 332364, -1],
['Ohio', 2320596, 2776683, 174266, 44310, 5315855, -1],
['Oklahoma', 420375, 949136, 83481, 0, 1452992, -1],
['Oregon', 991580, 774080, 93875, 49247, 1908782, 1],
['Pennsylvania', 2874136, 2945302, 144826, 49334, 6013598, -1],
['Rhode Island', 227062, 166454, 14700, 6171, 414387, 1, {
lat: -0.7,
lon: 1.7
}],
['South Carolina', 855373, 1155389, 49204, 13034, 2073000, -1],
['South Dakota', 117442, 227701, 20845, 0, 365988, -1],
['Tennessee', 868853, 1519926, 70286, 15952, 2475017, -1],
['Texas', 3877868, 4685047, 283492, 71558, 8917965, -1],
['Utah', 222858, 375006, 39608, 7695, 645167, -1],
['Vermont', 178573, 95369, 10078, 6758, 290778, 1, {
lat: 2
}],
['Virginia', 1981473, 1769443, 118274, 27638, 3896828, 1],
['Washington', 1727840, 1210370, 160356, 57571, 3156137, 1],
['West Virginia', 187519, 486304, 22958, 8016, 704797, -1],
['Wisconsin', 1382947, 1407028, 106470, 31016, 2927461, -1],
['Wyoming', 55973, 174419, 13287, 2515, 246194, -1]
],
maxVotes = 0,
demColor = 'rgba(74,131,240,0.80)',
repColor = 'rgba(220,71,71,0.80)',
libColor = 'rgba(240,190,50,0.80)',
grnColor = 'rgba(90,200,90,0.80)';
// Compute max votes to find relative sizes of bubbles
Highcharts.each(data, function(row) {
maxVotes = Math.max(maxVotes, row[5]);
});
// Build the chart
var chart = Highcharts.mapChart('container', {
chart: {
animation: false, // Disable animation, especially for zooming
events: {
load: function() {
addMapPie(this);
},
drilldown: function(e) {
if (!e.seriesOptions) {
var chart = this,
mapKey = 'countries/us/' + e.point.drilldown + '-all',
// Handle error, the timeout is cleared on success
fail = setTimeout(function() {
if (!Highcharts.maps[mapKey]) {
chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
fail = setTimeout(function() {
chart.hideLoading();
}, 1000);
}
}, 3000);
// Show the spinner
chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner
// Load the drilldown map
$.getScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', function() {
data = Highcharts.geojson(Highcharts.maps[mapKey]);
// Set a non-random bogus value
$.each(data, function(i) {
this.value = i;
});
chart.series.forEach(function(s) {
if (s.options.type === 'mappie') {
s.hide();
}
});
// Hide loading and add series
chart.hideLoading();
clearTimeout(fail);
chart.addSeriesAsDrilldown(e.point, {
name: e.point.name,
data: data,
dataLabels: {
enabled: true,
format: '{point.name}'
}
});
});
}
this.setTitle(null, {
text: e.point.name
});
},
drillup: function() {
this.setTitle(null, {
text: ''
});
this.series.forEach(function(s) {
if (s.options.type === 'mappie') {
s.show();
}
});
}
}
},
title: {
text: 'USA 2016 Presidential Election Results'
},
colorAxis: {
dataClasses: [{
from: -1,
to: 0,
color: 'rgba(244,91,91,0.5)',
name: 'Republican'
}, {
from: 0,
to: 1,
color: 'rgba(124,181,236,0.5)',
name: 'Democrat'
}, {
from: 2,
to: 3,
name: 'Libertarian',
color: libColor
}, {
from: 3,
to: 4,
name: 'Green',
color: grnColor
}]
},
mapNavigation: {
enabled: true
},
// Limit zoom range
yAxis: {
minRange: 2300
},
tooltip: {
useHTML: true
},
// Default options for the pies
plotOptions: {
mappie: {
borderColor: 'rgba(255,255,255,0.4)',
borderWidth: 1,
tooltip: {
headerFormat: ''
}
}
},
series: [{
mapData: Highcharts.maps['countries/us/us-all'],
data: data,
name: 'States',
borderColor: '#FFF',
showInLegend: false,
joinBy: ['name', 'id'],
keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes',
'sumVotes', 'value', 'pieOffset', 'drilldown'
],
tooltip: {
headerFormat: '',
pointFormatter: function() {
var hoverVotes = this.hoverVotes; // Used by pie only
return '<b>' + this.id + ' votes</b><br/>' +
Highcharts.map([
['Democrats', this.demVotes, demColor],
['Republicans', this.repVotes, repColor],
['Libertarians', this.libVotes, libColor],
['Green', this.grnVotes, grnColor]
].sort(function(a, b) {
return b[1] - a[1]; // Sort tooltip by most votes
}), function(line) {
return '<span style="color:' + line[2] +
// Colorized bullet
'">\u25CF</span> ' +
// Party and votes
(line[0] === hoverVotes ? '<b>' : '') +
line[0] + ': ' +
Highcharts.numberFormat(line[1], 0) +
(line[0] === hoverVotes ? '</b>' : '') +
'<br/>';
}).join('') +
'<hr/>Total: ' + Highcharts.numberFormat(this.sumVotes, 0);
}
}
}, {
name: 'Separators',
type: 'mapline',
data: Highcharts.geojson(Highcharts.maps['countries/us/us-all'], 'mapline'),
color: '#707070',
showInLegend: false,
enableMouseTracking: false
}, {
name: 'Connectors',
type: 'mapline',
color: 'rgba(130, 130, 130, 0.5)',
zIndex: 5,
showInLegend: false,
enableMouseTracking: false
}],
drilldown: {
activeDataLabelStyle: {
color: '#FFFFFF',
textDecoration: 'none',
textOutline: '1px #000000'
},
drillUpButton: {
relativeTo: 'spacingBox',
position: {
x: 0,
y: 60
}
}
}
});
function addMapPie(chart) {
// Add the pies after chart load, optionally with offset and connectors
Highcharts.each(chart.series[0].points, function(state) {
if (!state.id) {
return; // Skip points with no data, if any
}
var pieOffset = state.pieOffset || {},
centerLat = parseFloat(state.properties.latitude),
centerLon = parseFloat(state.properties.longitude);
// Add the pie for this state
chart.addSeries({
type: 'mappie',
name: state.id,
zIndex: 6, // Keep pies above connector lines
sizeFormatter: function() {
var yAxis = this.chart.yAxis[0],
zoomFactor = (yAxis.dataMax - yAxis.dataMin) /
(yAxis.max - yAxis.min);
return Math.max(
this.chart.chartWidth / 45 * zoomFactor, // Min size
this.chart.chartWidth / 11 * zoomFactor * state.sumVotes / maxVotes
);
},
tooltip: {
// Use the state tooltip for the pies as well
pointFormatter: function() {
return state.series.tooltipOptions.pointFormatter.call({
id: state.id,
hoverVotes: this.name,
demVotes: state.demVotes,
repVotes: state.repVotes,
libVotes: state.libVotes,
grnVotes: state.grnVotes,
sumVotes: state.sumVotes
});
}
},
data: [{
name: 'Democrats',
y: state.demVotes,
color: demColor
}, {
name: 'Republicans',
y: state.repVotes,
color: repColor
}, {
name: 'Libertarians',
y: state.libVotes,
color: libColor
}, {
name: 'Green',
y: state.grnVotes,
color: grnColor
}],
center: {
lat: centerLat + (pieOffset.lat || 0),
lon: centerLon + (pieOffset.lon || 0)
}
}, false);
// Draw connector to state center if the pie has been offset
if (pieOffset.drawConnector !== false) {
var centerPoint = chart.fromLatLonToPoint({
lat: centerLat,
lon: centerLon
}),
offsetPoint = chart.fromLatLonToPoint({
lat: centerLat + (pieOffset.lat || 0),
lon: centerLon + (pieOffset.lon || 0)
});
chart.series[2].addPoint({
name: state.id,
path: 'M' + offsetPoint.x + ' ' + offsetPoint.y +
'L' + centerPoint.x + ' ' + centerPoint.y
}, false);
}
});
// Only redraw once all pies and connectors have been added
chart.redraw();
}
#container {
min-width: 320px;
max-width: 800px;
height: 500px;
margin: 1em auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/maps/modules/data.js"></script>
<script src="https://code.highcharts.com/maps/modules/drilldown.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/us/us-all.js"></script>
<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<div id="container"></div>
Demo:
https://jsfiddle.net/BlackLabel/1d845opk/1/
EDIT
To add mappies also to the first level of drilldown you have to remove mappies series form the main view of the map when drilldown event occurs and create new ones for drilled data. It's quite difficult to explain exactly how to make it, so I prepared an example where each drilled level has sample data (you can get them from a server the same as drilled map data). I hope this example will help and you will see what's going on there.
Demo:
http://jsfiddle.net/BlackLabel/zLcnby79/
Thank you Wojciech Chmiel !
I did my map with the help of your post.
// New map-pie series type that also allows lat/lon as center option.
// Also adds a sizeFormatter option to the series, to allow dynamic sizing
// of the pies.
Highcharts.seriesType('mappie', 'pie', {
center: null, // Can't be array by default anymore
clip: true, // For map navigation
states: {
hover: {
halo: {
size: 5
}
}
},
dataLabels: {
enabled: false
}
}, {
getCenter: function() {
var options = this.options,
chart = this.chart,
slicingRoom = 2 * (options.slicedOffset || 0);
if (!options.center) {
options.center = [null, null]; // Do the default here instead
}
// Replace lat/lon with plotX/plotY
if (options.center.plotX !== undefined) {
options.center = [options.center.plotX, options.center.plotY];
}
// Handle dynamic size
if (options.sizeFormatter) {
options.size = options.sizeFormatter.call(this);
}
// Call parent function
var result = Highcharts.seriesTypes.pie.prototype.getCenter.call(this);
// Must correct for slicing room to get exact pixel pos
result[0] -= slicingRoom;
result[1] -= slicingRoom;
return result;
},
translate: function (p) {
this.options.center = this.userOptions.center;
this.center = this.getCenter();
return Highcharts.seriesTypes.pie.prototype.translate.call(this, p);
}
});
var data = [
// state, demVotes, repVotes, libVotes, grnVotes, sumVotes, winner, drilldown
['CAPLINA-OCONA', 729547, 1318255, 44467, 9391, 2101660, -1, 'aaa01'],
['CHAPARRA-CHINCHA', 116454, 163387, 18725, 5735, 304301, -1, 'aaa02'],
['CANETE-FORTALEZA', 1161167, 1252401, 106327, 34345, 2554240, -1, 'aaa03'],
['HUARMEY-CHICAMA', 380494, 684782, 29829, 9473, 1104578, -1, 'aaa04'],
['JEQUETEPEQUE-ZARUMILLA', 8577206, 4390272, 467370, 271047, 13705895, 1, 'aaa05'],
['MARANON', 1338870, 1202484, 144121, 38437, 2723912, 1, 'aaa06'],
['AMAZONAS', 897572, 673215, 48676, 22841, 1642304, 1, 'aaa07'],
['HUALLAGA', 235603, 185127, 14757, 6103, 441590, 1, 'aaa08'],
['UCAYALI', 282830, 12723, 4906, 4258, 304717, 1, 'aaa09'],
['MANTARO', 4504975, 4617886, 207043, 64399, 9394303, -1, 'aaa10'],
['PAMPAS-APURIMAC', 1877963, 2089104, 125306, 0, 4092373, -1, 'aaa11'],
['URUBAMBA-VILCANOTA', 266891, 128847, 15954, 12737, 424429, 1, 'aaa12'],
['MADRE DE DIOS', 189765, 409055, 28331, 8496, 635647, -1, 'aaa13'],
['TITICACA', 2977498, 2118179, 208682, 74112, 5378471, 1, 'aaa14']
],
maxVotes = 0,
demColor = 'rgba(74,131,240,0.80)',
repColor = 'rgba(220,71,71,0.80)',
libColor = 'rgba(240,190,50,0.80)',
grnColor = 'rgba(90,200,90,0.80)';
// Compute max votes to find relative sizes of bubbles
Highcharts.each(data, function(row) {
maxVotes = Math.max(maxVotes, row[5]);
});
// Build the chart
var chart = Highcharts.mapChart('container', {
chart: {
animation: false, // Disable animation, especially for zooming
events: {
load: function() {
addMapPie(this);
},
drilldown: function(e) {
if (!e.seriesOptions) {
var chart = this,
//mapKey = 'countries/us/' + e.point.drilldown + '-all',
mapKey = 'paises/pe/' + e.point.drilldown,
ruta = e.point.drilldown,
// Handle error, the timeout is cleared on success
fail = setTimeout(function() {
if (!Highcharts.maps[mapKey]) {
chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
fail = setTimeout(function() {
chart.hideLoading();
}, 1000);
}
}, 3000);
// Show the spinner
chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner
// Load the drilldown map
//$.getScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', function() {
//$.getScript('http://test1.ana.gob.pe/prueba-mappies/' + ruta + '.js', function () {
$.getScript('https://aplicaciones01.ana.gob.pe/mappies/' + ruta + '.js', function () {
data = Highcharts.geojson(Highcharts.maps[mapKey]);
// Set a non-random bogus value
$.each(data, function(i) {
this.value = i;
});
chart.series.forEach(function(s) {
if (s.options.type === 'mappie') {
s.hide();
}
});
// Hide loading and add series
chart.hideLoading();
clearTimeout(fail);
chart.addSeriesAsDrilldown(e.point, {
name: e.point.name,
data: data,
dataLabels: {
enabled: true,
format: '{point.name}'
}
});
});
}
this.setTitle(null, {
text: e.point.name
});
},
drillup: function() {
this.setTitle(null, {
text: ''
});
this.series.forEach(function(s) {
if (s.options.type === 'mappie') {
s.show();
}
});
}
}
},
title: {
text: 'Resultados'
},
colorAxis: {
dataClasses: [{
from: -1,
to: 0,
color: 'rgba(244,91,91,0.5)',
name: 'Republican'
}, {
from: 0,
to: 1,
color: 'rgba(124,181,236,0.5)',
name: 'Democrat'
}, {
from: 2,
to: 3,
name: 'Libertarian',
color: libColor
}, {
from: 3,
to: 4,
name: 'Green',
color: grnColor
}]
},
mapNavigation: {
enabled: true //Para el zoom (+ -)
},
// Limit zoom range
yAxis: {
minRange: 2300
},
tooltip: {
useHTML: true
},
// Default options for the pies
plotOptions: {
mappie: {
borderColor: 'rgba(255,255,255,0.4)',
borderWidth: 1,
tooltip: {
headerFormat: ''
}
}
},
series: [{
mapData: Highcharts.maps['paises/pe/aaa-all'],
data: data,
name: 'States',
borderColor: '#FFF',
showInLegend: false,
joinBy: ['name', 'id'],
//keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes',
// 'sumVotes', 'value', 'pieOffset'],
keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes', 'sumVotes', 'value', 'drilldown'],
tooltip: {
headerFormat: '',
pointFormatter: function () {
var hoverVotes = this.hoverVotes; // Used by pie only
return '<b>' + this.id + ' votes</b><br/>' +
Highcharts.map([
['Democrats', this.demVotes, demColor],
['Republicans', this.repVotes, repColor],
['Libertarians', this.libVotes, libColor],
['Green', this.grnVotes, grnColor]
].sort(function (a, b) {
return b[1] - a[1]; // Sort tooltip by most votes
}), function (line) {
return '<span style="color:' + line[2] +
// Colorized bullet
'">\u25CF</span> ' +
// Party and votes
(line[0] === hoverVotes ? '<b>' : '') +
line[0] + ': ' +
Highcharts.numberFormat(line[1], 0) +
(line[0] === hoverVotes ? '</b>' : '') +
'<br/>';
}).join('') +
'<hr/>Total: ' + Highcharts.numberFormat(this.sumVotes, 0);
}
}
}],
drilldown: {
activeDataLabelStyle: {
color: '#FFFFFF',
textDecoration: 'none',
textOutline: '1px #000000'
},
drillUpButton: {
relativeTo: 'spacingBox',
position: {
x: 0,
y: 60
}
}
}
});
function addMapPie(chart) {
// Add the pies after chart load, optionally with offset and connectors
Highcharts.each(chart.series[0].points, function(state) {
//if (!state.id) {
if (!state.id || !state.properties) {
return; // Skip points with no data, if any
}
var pieOffset = state.pieOffset || {},
centerLat = parseFloat(state.properties.latitude),
centerLon = parseFloat(state.properties.longitude);
// Add the pie for this state
chart.addSeries({
type: 'mappie',
name: state.id,
zIndex: 6, // Keep pies above connector lines
sizeFormatter: function () {
var yAxis = this.chart.yAxis[0],
zoomFactor = (yAxis.dataMax - yAxis.dataMin) /
(yAxis.max - yAxis.min);
return Math.max(
this.chart.chartWidth / 45 * zoomFactor, // Min size
this.chart.chartWidth / 11 * zoomFactor * state.sumVotes / maxVotes
);
},
/*****/
tooltip: {
// Use the state tooltip for the pies as well
pointFormatter: function () {
return state.series.tooltipOptions.pointFormatter.call({
id: state.id,
hoverVotes: this.name,
demVotes: state.demVotes,
repVotes: state.repVotes,
libVotes: state.libVotes,
grnVotes: state.grnVotes,
sumVotes: state.sumVotes
});
}
},
data: [{
name: 'Democrats',
y: state.demVotes,
color: demColor
}, {
name: 'Republicans',
y: state.repVotes,
color: repColor
}, {
name: 'Libertarians',
y: state.libVotes,
color: libColor
}, {
name: 'Green',
y: state.grnVotes,
color: grnColor
}],
center: {
/*lat: centerLat + (pieOffset.lat || 0),
lon: centerLon + (pieOffset.lon || 0)*/
plotX: state.plotX,
plotY: state.plotY
}
}, false);
});
// Only redraw once all pies and connectors have been added
chart.redraw();
}
#container {
min-width: 320px;
max-width: 800px;
height: 500px;
margin: 1em auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<script src="https://aplicaciones01.ana.gob.pe/mappies/AAA_psad56_simp.js"></script>
<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<div id="container"></div>
Here:
- https://jsfiddle.net/JMarcia/w06k5zog/17/

Google Charts: Remove default Sort for x-axis

Is there a way to remove the default sort for the x-axis? It automatically sorts from A-Z but I want to have it as January - December.
Chart Image :
For the missing months for each year and product type, I've auto generated them in PHP(where my final code is). So it would look like:
["January",0,"Apitong","2018","Analog"],["January",0,"Apitong","2018","Digital"],["January",0,"Apitong","2018","Internet"],["February",0,"Apitong","2018","Analog"],["February",0,"Apitong","2018","Digital"], .. etc
My Sample Code: JSFiddle
google.charts.load('current', {
callback: function() {
var data = google.visualization.arrayToDataTable([
['Month', 'Amount', 'Area', 'Year', 'Product Type'],
['January', 3300, 'Apitong', 2015, 'Analog'],
['February', 1000, 'Apitong', 2015, 'Analog'],
['March', 2000, 'Apitong', 2015, 'Analog'],
]);
google.visualization.events.addListener(product, 'ready', drawChart);
function drawChart() {
var areaData = new google.visualization.DataView(area.getDataTable());
var filters = [{
column: 2,
value: area.getState().selectedValues[0]
}
];
// group by 'Group' / 'Year'
var dataGroup = google.visualization.data.group(
areaData, [0, 3], [{
column: 1,
aggregation: google.visualization.data.sum,
type: 'number',
label: 'Sum'
}, {
column: 1,
aggregation: google.visualization.data.count,
type: 'number',
label: 'Count'
}]
);
dataGroup.sort([{
column: 0
}, {
column: 1
}]);
var ColumnChart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'productssold_chart_div',
'dataTable': view
});
ColumnChart.draw();
}
},
packages: ['controls', 'corechart']
});
when using a Discrete axis ('string' values),
the axis will sort by the order of the rows in the data table
in this case, the rows are set to alphabetical as a result of using static method --> data.group
to correct this issue, an array of month names is used to build a custom sort order
a new column is added to finalData and the index from the array is used as the order
// build final data table
var monthOrder = [
'January', 'February', 'March',
'April', 'May', 'June',
'July', 'August', 'September',
'October', 'November', 'December'
];
var finalData = new google.visualization.DataTable({
cols: [{
label: 'Group',
type: 'string'
}, {
label: 'Amount',
type: 'number'
}, {
label: 'Count',
type: 'number'
}, {
label: 'Sort',
type: 'number'
}]
});
// add row for each month AMOUNT | COUNT
var rowMonth = null;
var rowIndex = null;
for (var i = 0; i < dataGroup.getNumberOfRows(); i++) {
if (rowMonth !== dataGroup.getValue(i, 0)) {
rowMonth = dataGroup.getValue(i, 0);
rowIndex = finalData.addRow();
finalData.setValue(rowIndex, 0, rowMonth);
}
for (var x = 1; x < finalData.getNumberOfColumns(); x++) {
switch (finalData.getColumnLabel(x)) {
case 'Amount':
finalData.setValue(rowIndex, x, dataGroup.getValue(i, 2).toString());
break;
case 'Count':
finalData.setValue(rowIndex, x, dataGroup.getValue(i, 3).toString());
break;
case 'Sort':
finalData.setValue(rowIndex, x, monthOrder.indexOf(rowMonth));
break;
}
}
}
finalData.sort([{column: 3}]);
see following working snippet...
google.charts.load('current', {
callback: function() {
var data = google.visualization.arrayToDataTable([
['Month', 'Amount', 'Area', 'Year', 'Product Type'],
['February', 1000, 'Apitong', 2015, 'Analog'],
['February', 1700, 'Apitong', 2015, 'Internet'],
['February', 1200, 'Avenida Veteranos', 2015, 'Digital'],
['February', 2800, 'Brgy. Baras', 2015, 'Internet'],
['February', 2150, 'Avenida Veteranos', 2018, 'Digital'],
['February', 2700, 'Apitong', 2018, 'Internet'],
['February', 2500, 'Brgy. Baras', 2018, 'Internet'],
['March', 2000, 'Apitong', 2015, 'Digital'],
['March', 2400, 'Avenida Veteranos', 2015, 'Digital'],
['March', 1600, 'Brgy. Baras', 2015, 'Internet'],
['March', 3000, 'Avenida Veteranos', 2018, 'Analog'],
['March', 1400, 'Apitong', 2018, 'Digital'],
['January', 3300, 'Avenida Veteranos', 2015, 'Analog'],
['March', 2000, 'Brgy. Baras', 2018, 'Analog'],
['January', 2600, 'Brgy. Baras', 2015, 'Internet'],
['January', 1800, 'Apitong', 2015, 'Digital'],
['January', 2100, 'Brgy. Baras', 2015, 'Analog']
]);
var area = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'filter_productssold_area_div',
'dataTable': data,
'options': {
'filterColumnLabel': 'Area',
'ui': {
'allowTyping': false,
'allowMultiple': false,
'allowNone': false,
'sortValues': false,
'label': 'Choose Area',
}
}
});
var year = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'filter_productssold_year_div',
'dataTable': data,
'options': {
'filterColumnLabel': 'Year',
'ui': {
'allowTyping': false,
'allowMultiple': false,
'allowNone': false,
'sortValues': false,
'label': 'Choose Year',
}
}
});
var product = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'filter_productssold_product_div',
'dataTable': data,
'options': {
'filterColumnLabel': 'Product Type',
'ui': {
'allowTyping': false,
'allowMultiple': true,
'allowNone': true,
'sortValues': false,
'label': 'Choose Product',
}
}
});
google.visualization.events.addListener(area, 'ready', drawChart);
google.visualization.events.addListener(area, 'statechange', drawChart);
google.visualization.events.addListener(year, 'ready', drawChart);
google.visualization.events.addListener(year, 'statechange', drawChart);
google.visualization.events.addListener(product, 'ready', drawChart);
google.visualization.events.addListener(product, 'statechange', drawChart);
function drawChart() {
var areaData = new google.visualization.DataView(area.getDataTable());
var filters = [{
column: 2,
value: area.getState().selectedValues[0]
}
];
var selectedYear = year.getState().selectedValues;
if (typeof selectedYear !== 'undefined' && selectedYear.length > 0) {
filters.push({
column: 3,
test: function(value, row, column, table) {
return (selectedYear.indexOf(table.getValue(row, column)) > -1);
}
});
}
var selectedProducts = product.getState().selectedValues;
if (typeof selectedProducts !== 'undefined' && selectedProducts.length > 0) {
filters.push({
column: 4,
test: function(value, row, column, table) {
return (selectedProducts.indexOf(table.getValue(row, column)) > -1);
}
});
}
areaData.setRows(areaData.getFilteredRows(filters));
// group by 'Group' / 'Year'
var dataGroup = google.visualization.data.group(
areaData, [0, 3], [{
column: 1,
aggregation: google.visualization.data.sum,
type: 'number',
label: 'Sum'
}, {
column: 1,
aggregation: google.visualization.data.count,
type: 'number',
label: 'Count'
}]
);
dataGroup.sort([{
column: 0
}, {
column: 1
}]);
// build final data table
var monthOrder = [
'January', 'February', 'March',
'April', 'May', 'June',
'July', 'August', 'September',
'October', 'November', 'December'
];
var finalData = new google.visualization.DataTable({
cols: [{
label: 'Group',
type: 'string'
}, {
label: 'Amount',
type: 'number'
}, {
label: 'Count',
type: 'number'
}, {
label: 'Sort',
type: 'number'
}]
});
// add row for each month AMOUNT | COUNT
var rowMonth = null;
var rowIndex = null;
for (var i = 0; i < dataGroup.getNumberOfRows(); i++) {
if (rowMonth !== dataGroup.getValue(i, 0)) {
rowMonth = dataGroup.getValue(i, 0);
rowIndex = finalData.addRow();
finalData.setValue(rowIndex, 0, rowMonth);
}
for (var x = 1; x < finalData.getNumberOfColumns(); x++) {
switch (finalData.getColumnLabel(x)) {
case 'Amount':
finalData.setValue(rowIndex, x, dataGroup.getValue(i, 2).toString());
break;
case 'Count':
finalData.setValue(rowIndex, x, dataGroup.getValue(i, 3).toString());
break;
case 'Sort':
finalData.setValue(rowIndex, x, monthOrder.indexOf(rowMonth));
break;
}
}
}
finalData.sort([{column: 3}]);
var view = new google.visualization.DataView(finalData);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}]);
var ColumnChart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'productssold_chart_div',
'dataTable': view
});
ColumnChart.draw();
}
area.draw();
year.draw();
product.draw();
},
packages: ['controls', 'corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="filter_productssold_area_div"></div>
<div id="filter_productssold_year_div"></div>
<div id="filter_productssold_product_div"></div>
<div id="productssold_chart_div"></div>

Interval (step) for seconds in kendo ui chart

I am working on Kendo chart. I am trying to load date on the X axis and decimal value on Y.
I have generated 500 points using controller. Here is my controller.
List<jsonmodel> arrret = new List<jsonmodel>();
DateTime start = new DateTime(2015, 09, 14, 01, 20, 00);
Random rnd = new Random();
for (int i = 0; i < 500; i++)
{
decimal randomnumber = rnd.Next(10, 40);
DateTime secondsincreament = new DateTime();
secondsincreament = start;
arrret.Add(new jsonmodel()
{
close = randomnumber,
date = secondsincreament.ToString(),
});
start = start.AddSeconds(3);
}
return Json(arrret, JsonRequestBehavior.AllowGet);
I have started from 14/09/2015 01:20:00 and incremented 3 seconds with each loop for X axis and a random number for Y axis.
Using ajax in Jquery, I have created and array and pushed points to that array.
dataSource.push({ "x": new Date(data.date), "y": data.close });
And then, the Kendo chart goes as following.
$("#chart").kendoChart({
title: {
text: "time stamp chart"
},
dataSource: {
data: dataSource
},
series: [{
type: "scatterLine",
aggregate: "avg",
xField: "x",
yField: "y",
}],
xAxis: {
min: new Date("2015/09/14 01:18:00"),
max: new Date("2015/09/14 01:46:00"),
labels: {
template: "#= kendo.toString(value,'MM/dd/yyyy HH:mm:ss')#",
baseUnit: "seconds",
},
crosshair: {
visible: true,
tooltip: {
template: "#= kendo.toString(value,'MM/dd/yyyy HH:mm:ss')#",
visible: true,
},
},
},
yAxis: {
crosshair: {
visible: true,
tooltip: {
visible: true,
},
},
},
autoBaseUnitSteps: {
seconds: [3]
}
});
Problem is, Data is loading properly on the chart but not all dates (with seconds generated from the controller) are displayed on X axis.
I cant figure how to set interval (steps) for seconds on scatterLine chart.
Can anyone please help me out?
Thanks

Bootstrap datepicker disable feature years

I want to disable future years in bootstarp datepicker calender.
I tried following code,
$('.dpd3').datepicker({
format: " yyyy",
viewMode: "years",
endDate: now(),
minViewMode: "years"
});
Thanks
Try this....
$(function(){
$('.datepicker').datepicker({
format: 'mm-dd-yyyy',
endDate: '+0d',
autoclose: true
});
});
http://jsfiddle.net/tjnicolaides/cjp7y/
$(function () {
var nowDate = new Date();
var today = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate() + 1, 0, 0, 0, 0) ;
$('#Inputstartdatepkr').datetimepicker({
language: 'en',
pick12HourFormat: true,
pickSeconds: false,
startDate: today
});
});