Highcharts Line Chart Drill down not working properly - javascript

In my application I have a Line chart showing employee head count variation in several departments over several years. Then when I click on a one data series(Ex: Department A) I need to show a drill down of that selected department. I have added the drill dwon code and drill down data to the chart definition. Seems it's not working properly. I couldn't find what's wrong here. Is there a workaround for this one. Sample code is as following.
http://jsfiddle.net/yasirunilan/qja2s3rb/9/
var chart = new Highcharts.Chart({
chart: {
renderTo: "container-main-bar",
type: "line"
},
title: {
text: null
},
series: [{
"name": "Department A",
"data": [{
"name": "Month1",
"y": 27,
"drilldown": "levelA2"
},
{
"name": "Month2",
"y": 24,
"drilldown": "levelA2"
},
{
"name": "Month3",
"y": 22,
"drilldown": "levelA2"
},
{
"name": "Month4",
"y": 26,
"drilldown": "levelA2"
},
{
"name": "Month5",
"y": 21,
"drilldown": "levelA2"
},
{
"name": "Month6",
"y": 22,
"drilldown": "levelA2"
},
{
"name": "Month7",
"y": 23,
"drilldown": "levelA2"
},
{
"name": "Month8",
"y": 24,
"drilldown": "levelA2"
},
{
"name": "Month9",
"y": 21,
"drilldown": "levelA2"
},
{
"name": "Month10",
"y": 20,
"drilldown": "levelA2"
},
{
"name": "Month11",
"y": 22,
"drilldown": "levelA2"
},
{
"name": "Month12",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month13",
"y": 23,
"drilldown": "levelA2"
},
{
"name": "Month14",
"y": 24,
"drilldown": "levelA2"
},
{
"name": "Month15",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month16",
"y": 26,
"drilldown": "levelA2"
},
{
"name": "Month17",
"y": 24,
"drilldown": "levelA2"
},
{
"name": "Month18",
"y": 23,
"drilldown": "levelA2"
},
{
"name": "Month19",
"y": 23,
"drilldown": "levelA2"
},
{
"name": "Month20",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month21",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month22",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month23",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month24",
"y": 25,
"drilldown": "levelA2"
}
],
"drilldown": {
"series": [{
"name": 'Headcount',
"id": 'levelA2',
"data": [{
"name": "Month1",
"y": 10,
},
{
"name": "Month2",
"y": 12,
},
{
"name": "Month3",
"y": 11,
},
{
"name": "Month4",
"y": 10,
},
{
"name": "Month5",
"y": 9,
},
{
"name": "Month6",
"y": 8,
},
{
"name": "Month7",
"y": 10,
},
{
"name": "Month8",
"y": 12,
},
{
"name": "Month9",
"y": 11,
},
{
"name": "Month10",
"y": 13,
},
{
"name": "Month11",
"y": 14,
},
{
"name": "Month12",
"y": 10,
},
{
"name": "Month13",
"y": 9,
},
{
"name": "Month14",
"y": 8,
},
{
"name": "Month15",
"y": 11,
},
{
"name": "Month16",
"y": 10,
},
{
"name": "Month17",
"y": 9,
},
{
"name": "Month18",
"y": 10,
},
{
"name": "Month19",
"y": 11,
},
{
"name": "Month20",
"y": 12,
},
{
"name": "Month21",
"y": 13,
},
{
"name": "Month22",
"y": 10,
},
{
"name": "Month23",
"y": 11,
},
{
"name": "Month24",
"y": 12,
}
]
}]
}
}, ],
xAxis: {
categories: [{
"name": "2013",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2014",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2015",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2016",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2017",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2018",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
}
]
},
yAxis: [{ // Primary yAxis
title: {
text: 'No. of Employees'
},
}],
});

first you have to add drilldown.js in your HTML
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
and drilldown object is wrongly entered in the input JSON object. it should come out of series. below is the correct format. Please have a look in the code snippet.
$(function() {
var chart = new Highcharts.Chart({
chart: {
renderTo: "container-main-bar",
type: "line"
},
title: {
text: null
},
series: [{
"name": "Department A",
"data": [{
"name": "Month1",
"y": 27,
"drilldown": "levelA2"
},
{
"name": "Month2",
"y": 24,
"drilldown": "levelA2"
},
{
"name": "Month3",
"y": 22,
"drilldown": "levelA2"
},
{
"name": "Month4",
"y": 26,
"drilldown": "levelA2"
},
{
"name": "Month5",
"y": 21,
"drilldown": "levelA2"
},
{
"name": "Month6",
"y": 22,
"drilldown": "levelA2"
},
{
"name": "Month7",
"y": 23,
"drilldown": "levelA2"
},
{
"name": "Month8",
"y": 24,
"drilldown": "levelA2"
},
{
"name": "Month9",
"y": 21,
"drilldown": "levelA2"
},
{
"name": "Month10",
"y": 20,
"drilldown": "levelA2"
},
{
"name": "Month11",
"y": 22,
"drilldown": "levelA2"
},
{
"name": "Month12",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month13",
"y": 23,
"drilldown": "levelA2"
},
{
"name": "Month14",
"y": 24,
"drilldown": "levelA2"
},
{
"name": "Month15",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month16",
"y": 26,
"drilldown": "levelA2"
},
{
"name": "Month17",
"y": 24,
"drilldown": "levelA2"
},
{
"name": "Month18",
"y": 23,
"drilldown": "levelA2"
},
{
"name": "Month19",
"y": 23,
"drilldown": "levelA2"
},
{
"name": "Month20",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month21",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month22",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month23",
"y": 25,
"drilldown": "levelA2"
},
{
"name": "Month24",
"y": 25,
"drilldown": "levelA2"
}
]
} ],
"drilldown": {
"series": [{
"name": 'Headcount',
"id": 'levelA2',
"data": [{
"name": "Month1",
"y": 10,
},
{
"name": "Month2",
"y": 12,
},
{
"name": "Month3",
"y": 11,
},
{
"name": "Month4",
"y": 10,
},
{
"name": "Month5",
"y": 9,
},
{
"name": "Month6",
"y": 8,
},
{
"name": "Month7",
"y": 10,
},
{
"name": "Month8",
"y": 12,
},
{
"name": "Month9",
"y": 11,
},
{
"name": "Month10",
"y": 13,
},
{
"name": "Month11",
"y": 14,
},
{
"name": "Month12",
"y": 10,
},
{
"name": "Month13",
"y": 9,
},
{
"name": "Month14",
"y": 8,
},
{
"name": "Month15",
"y": 11,
},
{
"name": "Month16",
"y": 10,
},
{
"name": "Month17",
"y": 9,
},
{
"name": "Month18",
"y": 10,
},
{
"name": "Month19",
"y": 11,
},
{
"name": "Month20",
"y": 12,
},
{
"name": "Month21",
"y": 13,
},
{
"name": "Month22",
"y": 10,
},
{
"name": "Month23",
"y": 11,
},
{
"name": "Month24",
"y": 12,
}
]
}]
},
xAxis: {
categories: [{
"name": "2013",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2014",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2015",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2016",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2017",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
{
"name": "2018",
"categories": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
}
]
},
yAxis: [{ // Primary yAxis
title: {
text: 'No. of Employees'
},
}],
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
<script src="http://blacklabel.github.io/grouped_categories/grouped-categories.js"></script>
<div id="container-main-bar"></div>

Related

Recharts: Bar Chart Grouped on XAxis with LineChart on seperate XAxis (different data)

I have a barchart displaying groups of bars for each month in a 3 month period.
I have now been asked to add a line chart with the daily views spanning the 3 month period to chart like this (the red line i've drawn in the below image is the linechart of views):
I have tried several strategies, and all of them were unsuccessful. I'm currently at a loss to how i should approach this, and any ideas are appreciated. if worse comes to worse, i can always render two seperate charts and absolutely position one above the other, but i thought i'd try here for suggestions before resorting to that. I am not above changing my data structure, so long as i can keep the bar's grouped by month, and plot the line linearly over the 3 month period
The data structure i am currently using is something like below:
[
[
{
"month": "May",
"messages": {
"name": "messages",
"growth": 3,
"value": 35
},
"views": {
"name": "views",
"growth": 13,
"value": 61
},
"shares": {
"name": "shares",
"growth": 17,
"value": 193
},
"favorites": {
"name": "favorites",
"growth": 12,
"value": 164
}
},
{
"month": "June",
"messages": {
"name": "messages",
"growth": 22,
"value": 203
},
"views": {
"name": "views",
"growth": 6,
"value": 31
},
"shares": {
"name": "shares",
"growth": 21,
"value": 231
},
"favorites": {
"name": "favorites",
"growth": 19,
"value": 30
}
},
{
"month": "July",
"messages": {
"name": "messages",
"growth": 16,
"value": 196
},
"views": {
"name": "views",
"growth": 16,
"value": 107
},
"shares": {
"name": "shares",
"growth": 13,
"value": 59
},
"favorites": {
"name": "favorites",
"growth": 2,
"value": 175
}
}
],
[
{
"month": "May",
"messages": {
"name": "messages",
"growth": 20,
"value": 25
},
"views": {
"name": "views",
"growth": 21,
"value": 104
},
"shares": {
"name": "shares",
"growth": 14,
"value": 124
},
"favorites": {
"name": "favorites",
"growth": 1,
"value": 164
}
},
{
"month": "June",
"messages": {
"name": "messages",
"growth": 10,
"value": 168
},
"views": {
"name": "views",
"growth": 16,
"value": 128
},
"shares": {
"name": "shares",
"growth": 14,
"value": 79
},
"favorites": {
"name": "favorites",
"growth": 8,
"value": 187
}
},
{
"month": "July",
"messages": {
"name": "messages",
"growth": 21,
"value": 136
},
"views": {
"name": "views",
"growth": 9,
"value": 241
},
"shares": {
"name": "shares",
"growth": 20,
"value": 29
},
"favorites": {
"name": "favorites",
"growth": 0,
"value": 56
}
}
],
[
{
"month": "May",
"messages": {
"name": "messages",
"growth": 7,
"value": 212
},
"views": {
"name": "views",
"growth": 19,
"value": 90
},
"shares": {
"name": "shares",
"growth": 6,
"value": 175
},
"favorites": {
"name": "favorites",
"growth": 6,
"value": 66
}
},
{
"month": "June",
"messages": {
"name": "messages",
"growth": 8,
"value": 179
},
"views": {
"name": "views",
"growth": 12,
"value": 81
},
"shares": {
"name": "shares",
"growth": 9,
"value": 200
},
"favorites": {
"name": "favorites",
"growth": 2,
"value": 236
}
},
{
"month": "July",
"messages": {
"name": "messages",
"growth": 10,
"value": 200
},
"views": {
"name": "views",
"growth": 4,
"value": 105
},
"shares": {
"name": "shares",
"growth": 17,
"value": 188
},
"favorites": {
"name": "favorites",
"growth": 8,
"value": 77
}
}
],
[
{
"month": "May",
"messages": {
"name": "messages",
"growth": 17,
"value": 148
},
"views": {
"name": "views",
"growth": 16,
"value": 152
},
"shares": {
"name": "shares",
"growth": 24,
"value": 79
},
"favorites": {
"name": "favorites",
"growth": 12,
"value": 129
}
},
{
"month": "June",
"messages": {
"name": "messages",
"growth": 17,
"value": 202
},
"views": {
"name": "views",
"growth": 3,
"value": 132
},
"shares": {
"name": "shares",
"growth": 15,
"value": 186
},
"favorites": {
"name": "favorites",
"growth": 15,
"value": 105
}
},
{
"month": "July",
"messages": {
"name": "messages",
"growth": 11,
"value": 83
},
"views": {
"name": "views",
"growth": 19,
"value": 192
},
"shares": {
"name": "shares",
"growth": 6,
"value": 114
},
"favorites": {
"name": "favorites",
"growth": 2,
"value": 109
}
}
],
[
{
"month": "May",
"messages": {
"name": "messages",
"growth": 9,
"value": 104
},
"views": {
"name": "views",
"growth": 24,
"value": 54
},
"shares": {
"name": "shares",
"growth": 17,
"value": 60
},
"favorites": {
"name": "favorites",
"growth": 1,
"value": 108
}
},
{
"month": "June",
"messages": {
"name": "messages",
"growth": 6,
"value": 80
},
"views": {
"name": "views",
"growth": 22,
"value": 214
},
"shares": {
"name": "shares",
"growth": 23,
"value": 38
},
"favorites": {
"name": "favorites",
"growth": 15,
"value": 156
}
},
{
"month": "July",
"messages": {
"name": "messages",
"growth": 21,
"value": 247
},
"views": {
"name": "views",
"growth": 16,
"value": 72
},
"shares": {
"name": "shares",
"growth": 17,
"value": 158
},
"favorites": {
"name": "favorites",
"growth": 12,
"value": 74
}
}
],
[
{
"month": "May",
"messages": {
"name": "messages",
"growth": 2,
"value": 193
},
"views": {
"name": "views",
"growth": 6,
"value": 250
},
"shares": {
"name": "shares",
"growth": 18,
"value": 167
},
"favorites": {
"name": "favorites",
"growth": 20,
"value": 98
}
},
{
"month": "June",
"messages": {
"name": "messages",
"growth": 25,
"value": 84
},
"views": {
"name": "views",
"growth": 21,
"value": 212
},
"shares": {
"name": "shares",
"growth": 0,
"value": 172
},
"favorites": {
"name": "favorites",
"growth": 14,
"value": 246
}
},
{
"month": "July",
"messages": {
"name": "messages",
"growth": 14,
"value": 90
},
"views": {
"name": "views",
"growth": 6,
"value": 47
},
"shares": {
"name": "shares",
"growth": 7,
"value": 234
},
"favorites": {
"name": "favorites",
"growth": 14,
"value": 181
}
}
],
[
{
"month": "May",
"messages": {
"name": "messages",
"growth": 10,
"value": 140
},
"views": {
"name": "views",
"growth": 1,
"value": 112
},
"shares": {
"name": "shares",
"growth": 20,
"value": 191
},
"favorites": {
"name": "favorites",
"growth": 12,
"value": 58
}
},
{
"month": "June",
"messages": {
"name": "messages",
"growth": 2,
"value": 250
},
"views": {
"name": "views",
"growth": 14,
"value": 109
},
"shares": {
"name": "shares",
"growth": 16,
"value": 159
},
"favorites": {
"name": "favorites",
"growth": 12,
"value": 89
}
},
{
"month": "July",
"messages": {
"name": "messages",
"growth": 24,
"value": 46
},
"views": {
"name": "views",
"growth": 6,
"value": 189
},
"shares": {
"name": "shares",
"growth": 11,
"value": 197
},
"favorites": {
"name": "favorites",
"growth": 19,
"value": 179
}
}
],
[
{
"month": "May",
"messages": {
"name": "messages",
"growth": 19,
"value": 52
},
"views": {
"name": "views",
"growth": 11,
"value": 86
},
"shares": {
"name": "shares",
"growth": 2,
"value": 63
},
"favorites": {
"name": "favorites",
"growth": 17,
"value": 133
}
},
{
"month": "June",
"messages": {
"name": "messages",
"growth": 9,
"value": 225
},
"views": {
"name": "views",
"growth": 1,
"value": 68
},
"shares": {
"name": "shares",
"growth": 23,
"value": 220
},
"favorites": {
"name": "favorites",
"growth": 7,
"value": 124
}
},
{
"month": "July",
"messages": {
"name": "messages",
"growth": 9,
"value": 171
},
"views": {
"name": "views",
"growth": 1,
"value": 221
},
"shares": {
"name": "shares",
"growth": 22,
"value": 191
},
"favorites": {
"name": "favorites",
"growth": 4,
"value": 95
}
}
]
]
And the code for rendering my chart is:
import React from 'react';
import {
BarChart, Bar, XAxis, YAxis,
Tooltip, LabelList, Legend, ResponsiveContainer
} from 'recharts';
const labels = {
messages:'Messages',
views:'Views',
shares:'Shares',
favorites:'Favorites'
};
const legendFormatter = (value,entry,index) => labels[value.split('.')[0]];
const tooltipFormatter = (value,name,props) => [value,legendFormatter(name)]
const renderCustomizedLabel = (fill) =>{
return (props) => {
const { x, y, width, value } = props;
console.log(props)
return (
<g>
<rect width={width} height={30} x={x} y={y-30} fill="#fff" />
<text x={x + width / 2} y={y - 12} fill={fill} textAnchor="middle" dominantBaseline="middle">
{value > 0 ?('+'+value):value}
</text>
</g>
);
};
};
const RenderChart = ({data})=>(<ResponsiveContainer height={400}>
<BarChart data={data}
style={{ backgroundColor:'#F4F4F4' }}
margin={{ top: 45, right: 20, left: -10, bottom: 15 }}
>
<XAxis dataKey="month" />
<YAxis/>
<Tooltip formatter={tooltipFormatter} />
<Legend formatter={legendFormatter} />
<Bar dataKey="messages.value" fill="#4A8A95" minPointSize={5}>
<LabelList dataKey="messages.growth" content={renderCustomizedLabel('#4A8A95')} />
</Bar>
<Bar dataKey="views.value" fill="#FBBE52" minPointSize={5}>
<LabelList dataKey="views.growth" content={renderCustomizedLabel('#FBBE52')} />
</Bar>
<Bar dataKey="shares.value" fill="#EA4646" minPointSize={5}>
<LabelList dataKey="shares.growth" content={renderCustomizedLabel('#EA4646')} />
</Bar>
<Bar dataKey="favorites.value" fill="#0467BA" minPointSize={5}>
<LabelList dataKey="favorites.growth" content={renderCustomizedLabel('#0467BA')} />
</Bar>
</BarChart>
</ResponsiveContainer>);

Javascript: Updating the property of a nested object in an array updates the same property for all similar objects

I came across this weird behavior in my code, where i am updating a single property of a nested object within an array of objects. Weirdness is that the same property for all similar objects is getting updated.
Code:
let financials = {
qr: {
controlData: [
{
"year": "2013",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": true
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
},
{
"year": "2014",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": true
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
},
{
"year": "2015",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": true
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
}
]
}
};
$('.checkbox.quarterly').click(function (e) {
try {
// var selectedYear = $('.dropdown.quarterly').dropdown('get value');
// var month = $(this).find('.checkbox-input').data('month');
// var prop = $(this).find('.checkbox-input').prop('checked');
// var targetObj = _.findWhere(financials.qr.controlData, { year: selectedYear });
// Values assumed
var selectedYear = '2013';
var month = 'Mar';
var prop = false;
var targetObj = _.findWhere(financials.qr.controlData, { year: selectedYear });
$.each(targetObj.quarters, function (key, quarter) {
if (quarter.month === month) {
quarter.isChecked = prop;
}
});
} catch (ex) {
console.log(ex);
}
});
Actual Output:
controlData: [
{
"year": "2013",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": false
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
},
{
"year": "2014",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": false
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
},
{
"year": "2015",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": false
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
}
]
Expected Output:
controlData: [
{
"year": "2013",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": false
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
},
{
"year": "2014",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": true
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
},
{
"year": "2015",
"quarters": [
{
"month": "Mar",
"name": "first",
"alias": "Q1",
"isChecked": true
},
{
"month": "Jun",
"name": "second",
"alias": "Q2",
"isChecked": true
},
{
"month": "Sep",
"name": "third",
"alias": "Q3",
"isChecked": true
},
{
"month": "Dec",
"name": "fourth",
"alias": "Q4",
"isChecked": true
}
]
}
]
Basically what i was trying to do is, to update the property 'isChecked' of a particular month whenever I click on the corresponding checkbox. My project is running on Laravel Mix with Webpack.
UPDATE:
This is how the controlData is being created:
let years = ['2013', '2014', '2015'];
let quarters = [
{
month: 'Mar',
name: 'first',
alias: 'Q1',
isChecked: true
},
{
month: 'Jun',
name: 'second',
alias: 'Q2',
isChecked: true
},
{
month: 'Sep',
name: 'third',
alias: 'Q3',
isChecked: true
},
{
month: 'Dec',
name: 'fourth',
alias: 'Q4',
isChecked: true
}
];
for(let x in years) {
let obj = {
year: years[x],
quarters: quarters
};
financials.qr.controlData.push(obj);
}
For me it seems to works just fine. Only the value for Mar 2013 is getting set to false.
Underscore v1.8.3
jQuery v3.3.2
https://jsfiddle.net/7o1tx49d/4/
You create independent arrays with independent objects by mapping copies of the objects.
financials.qr.controlData = years.map(year => ({
year,
quarters: quarters.map(o => Object.assign({}, o))
}));
var financials = { qr: {} },
quarters = [{ month: 'Mar', name: 'first', alias: 'Q1', isChecked: true }, { month: 'Jun', name: 'second', alias: 'Q2', isChecked: true }, { month: 'Sep', name: 'third', alias: 'Q3', isChecked: true }, { month: 'Dec', name: 'fourth', alias: 'Q4', isChecked: true }],
years = ['2013', '2014', '2015'];
financials.qr.controlData = years.map(year => ({
year,
quarters: quarters.map(o => Object.assign({}, o))
}));
var selectedYear = '2013',
month = 'Mar',
prop = false,
targetObj = _.findWhere(financials.qr.controlData, { year: selectedYear });
$.each(targetObj.quarters, function (key, quarter) {
if (quarter.month === month) {
quarter.isChecked = prop;
}
});
console.log(financials);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

month wise dataset dynamically

I am trying to create month wise data array for my chart. Combining all the sales and purchase value of each month
It will be really helpful who can help me in getting my expected output. I have attached the fiddle which I tried with my expected output to create chart
If possible, guide me with some java script functions which can be useful to me
http://jsfiddle.net/qjsgy6a6/2/
var mainData = [
{
"date": "2017-01-03",
"month": "JAN",
"sales": "200",
"purchase": "1000"
},
{
"date": "2017-01-18",
"month": "JAN",
"sales": "800",
"purchase": "2500"
},
{
"date": "2017-01-22",
"month": "JAN",
"sales": "400",
"purchase": "2100"
},
{
"date": "2017-02-20",
"month": "FEB",
"sales": "40",
"purchase": "90"
},
{
"date": "2017-02-28",
"month": "FEB",
"sales": "970",
"purchase": "2100"
},
{
"date": "2017-02-29",
"month": "FEB",
"sales": "3300",
"purchase": "2900"
},
{
"date": "2017-03-20",
"month": "MAR",
"sales": "600",
"purchase": "900"
}
]
// Expected Output - how can I achieve this
{
"data": [
{
"data": [
{
"event": "sales",
"inventory": [
{
"value": "200" //Jan
},
{
"value": "40" //Feb
},
{
"value": "600" //Mar
}
]
},
{
"event": "purchase",
"inventory": [
{
"value": "1000"
},
{
"value": "90"
},
{
"value": "900"
}
]
}
]
},
{
"data": [
{
"event": "sales",
"inventory": [
{
"value": "800"
},
{
"value": "970"
}
]
},
{
"event": "purchase",
"inventory": [
{
"value": "2500"
},
{
"value": "2100"
}
]
}
]
},
{
"data": [
{
"event": "sales",
"inventory": [
{
"value": "400"
},
{
"value": "3300"
}
]
},
{
"event": "purchase",
"inventory": [
{
"value": "2100"
},
{
"value": "2900"
}
]
}
]
}
]
}
You could use this function:
function transformData(data) {
return {
data: data.reduce ( (acc, item) => {
let i = acc.months.get(item.month) || 0;
acc.data[i] = acc.data[i] || {
data: [{
event: "sales",
inventory: []
}, {
event: "purchase",
inventory: []
}]
};
acc.data[i].data[0].inventory.push({ value: item.sales });
acc.data[i].data[1].inventory.push({ value: item.purchase });
acc.months.set(item.month, i+1);
return acc;
}, { months: new Map, data: [] } ).data
};
}
// Input
var data = [
{
"date": "2017-01-03",
"month": "JAN",
"sales": "200",
"purchase": "1000"
},
{
"date": "2017-01-18",
"month": "JAN",
"sales": "800",
"purchase": "2500"
},
{
"date": "2017-01-22",
"month": "JAN",
"sales": "400",
"purchase": "2100"
},
{
"date": "2017-02-20",
"month": "FEB",
"sales": "40",
"purchase": "90"
},
{
"date": "2017-02-28",
"month": "FEB",
"sales": "970",
"purchase": "2100"
},
{
"date": "2017-02-29",
"month": "FEB",
"sales": "3300",
"purchase": "2900"
},
{
"date": "2017-03-20",
"month": "MAR",
"sales": "600",
"purchase": "900"
}
];
// Conversion
var result = transformData(data);
// Output
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

AngularJS with Jquery Chosen Default Load

I'm using AngularJS and the jquery chosen plugin to populate a multiple select form. My Angular code has a service that is calling a node.js web service. The option list for the chosen select box is being populated from a json file while the value is being stored within model from the nodejs service. I've been using this link to guide me but now seem to be stuck.
I've included the code here.
My chosen options are being populated as such:
[
{"id": 1, "name": "00:00", "value": 0},
{"id": 2, "name": "00:15", "value": 900000},
{"id": 3, "name": "00:30", "value": 1800000}
...
]
But my model is being stored as:
meal.dinnerTimes = ["06:15","18:30"]
So when the model is loaded by the service and controller. The select box is always blank where I would expect to see
"06:15" and "18:30" already populated in this case
Any help would be appreciated
As you only have value with you while assigning model, use select as label for value in array syntax to have only value property assigned to the model.
Also note that you are not invoking callback function provided in MealSvc factory hence, value of model will never get set!
Plunker Demo
var app = angular.module("MealApp", ['MealService']);
var data = [{
"id": 1,
"name": "00:00",
"value": 0
}, {
"id": 2,
"name": "00:15",
"value": 900000
}, {
"id": 3,
"name": "00:30",
"value": 1800000
}, {
"id": 4,
"name": "00:45",
"value": 2700000
}, {
"id": 5,
"name": "01:00",
"value": 3600000
}, {
"id": 6,
"name": "01:15",
"value": 4500000
}, {
"id": 7,
"name": "01:30",
"value": 5400000
}, {
"id": 8,
"name": "01:45",
"value": 6300000
}, {
"id": 9,
"name": "02:00",
"value": 7200000
}, {
"id": 10,
"name": "02:15",
"value": 8100000
}, {
"id": 11,
"name": "02:30",
"value": 9000000
}, {
"id": 12,
"name": "02:45",
"value": 9900000
}, {
"id": 13,
"name": "03:00",
"value": 10800000
}, {
"id": 14,
"name": "03:15",
"value": 11700000
}, {
"id": 15,
"name": "03:30",
"value": 12600000
}, {
"id": 16,
"name": "03:45",
"value": 13500000
}, {
"id": 17,
"name": "04:00",
"value": 14400000
}, {
"id": 18,
"name": "04:15",
"value": 15300000
}, {
"id": 19,
"name": "04:30",
"value": 16200000
}, {
"id": 20,
"name": "04:45",
"value": 17100000
}, {
"id": 21,
"name": "05:00",
"value": 18000000
}, {
"id": 22,
"name": "05:15",
"value": 18900000
}, {
"id": 23,
"name": "05:30",
"value": 19800000
}, {
"id": 24,
"name": "05:45",
"value": 20700000
}, {
"id": 25,
"name": "06:00",
"value": 21600000
}, {
"id": 26,
"name": "06:15",
"value": 22500000
}, {
"id": 27,
"name": "06:30",
"value": 23400000
}, {
"id": 28,
"name": "06:45",
"value": 24300000
}, {
"id": 29,
"name": "07:00",
"value": 25200000
}, {
"id": 30,
"name": "07:15",
"value": 26100000
}, {
"id": 31,
"name": "07:30",
"value": 27000000
}, {
"id": 32,
"name": "07:45",
"value": 27900000
}, {
"id": 33,
"name": "08:00",
"value": 28800000
}, {
"id": 34,
"name": "08:15",
"value": 29700000
}, {
"id": 35,
"name": "08:30",
"value": 30600000
}, {
"id": 36,
"name": "08:45",
"value": 31500000
}, {
"id": 37,
"name": "09:00",
"value": 32400000
}, {
"id": 38,
"name": "09:15",
"value": 33300000
}, {
"id": 39,
"name": "09:30",
"value": 34200000
}, {
"id": 40,
"name": "09:45",
"value": 35100000
}, {
"id": 41,
"name": "10:00",
"value": 36000000
}, {
"id": 42,
"name": "10:15",
"value": 36900000
}, {
"id": 43,
"name": "10:30",
"value": 37800000
}, {
"id": 44,
"name": "10:45",
"value": 38700000
}, {
"id": 45,
"name": "11:00",
"value": 39600000
}, {
"id": 46,
"name": "11:15",
"value": 40500000
}, {
"id": 47,
"name": "11:30",
"value": 41400000
}, {
"id": 48,
"name": "11:45",
"value": 42300000
}, {
"id": 49,
"name": "12:00",
"value": 43200000
}, {
"id": 50,
"name": "12:15",
"value": 44100000
}, {
"id": 51,
"name": "12:30",
"value": 45000000
}, {
"id": 52,
"name": "12:45",
"value": 45900000
}, {
"id": 53,
"name": "13:00",
"value": 46800000
}, {
"id": 54,
"name": "13:15",
"value": 47700000
}, {
"id": 55,
"name": "13:30",
"value": 48600000
}, {
"id": 56,
"name": "13:45",
"value": 49500000
}, {
"id": 57,
"name": "14:00",
"value": 50400000
}, {
"id": 58,
"name": "14:15",
"value": 51300000
}, {
"id": 59,
"name": "14:30",
"value": 52200000
}, {
"id": 60,
"name": "14:45",
"value": 53100000
}, {
"id": 61,
"name": "15:00",
"value": 54000000
}, {
"id": 62,
"name": "15:15",
"value": 54900000
}, {
"id": 63,
"name": "15:30",
"value": 55800000
}, {
"id": 64,
"name": "15:45",
"value": 56700000
}, {
"id": 65,
"name": "16:00",
"value": 57600000
}, {
"id": 66,
"name": "16:15",
"value": 58500000
}, {
"id": 67,
"name": "16:30",
"value": 59400000
}, {
"id": 68,
"name": "16:45",
"value": 60300000
}, {
"id": 69,
"name": "17:00",
"value": 61200000
}, {
"id": 70,
"name": "17:15",
"value": 62100000
}, {
"id": 71,
"name": "17:30",
"value": 63000000
}, {
"id": 72,
"name": "17:45",
"value": 63900000
}, {
"id": 73,
"name": "18:00",
"value": 64800000
}, {
"id": 74,
"name": "18:15",
"value": 65700000
}, {
"id": 75,
"name": "18:30",
"value": 66600000
}, {
"id": 76,
"name": "18:45",
"value": 67500000
}, {
"id": 77,
"name": "19:00",
"value": 68400000
}, {
"id": 78,
"name": "19:15",
"value": 69300000
}, {
"id": 79,
"name": "19:30",
"value": 70200000
}, {
"id": 80,
"name": "19:45",
"value": 71100000
}, {
"id": 81,
"name": "20:00",
"value": 72000000
}, {
"id": 82,
"name": "20:15",
"value": 72900000
}, {
"id": 83,
"name": "20:30",
"value": 73800000
}, {
"id": 84,
"name": "20:45",
"value": 74700000
}, {
"id": 85,
"name": "21:00",
"value": 75600000
}, {
"id": 86,
"name": "21:15",
"value": 76500000
}, {
"id": 87,
"name": "21:30",
"value": 77400000
}, {
"id": 88,
"name": "21:45",
"value": 78300000
}, {
"id": 89,
"name": "22:00",
"value": 79200000
}, {
"id": 90,
"name": "22:15",
"value": 80100000
}, {
"id": 91,
"name": "22:30",
"value": 81000000
}, {
"id": 92,
"name": "22:45",
"value": 81900000
}, {
"id": 93,
"name": "23:00",
"value": 82800000
}, {
"id": 94,
"name": "23:15",
"value": 83700000
}, {
"id": 95,
"name": "23:30",
"value": 84600000
}, {
"id": 96,
"name": "23:45",
"value": 85500000
}];
app.directive('chosen', function() {
var linker = function(scope, element, attr) {
scope.$watch('availableTimes', function() {
element.triggerHandler('chosen:updated');
});
scope.$watch('MealSvc.get()', function() {
element.triggerHandler('chosen:updated');
});
element.chosen({
width: "95%"
});
};
return {
restrict: 'A',
link: linker
}
});
app.controller("MealCtrl", function MealCtrl($scope, $window, $http, MealSvc) {
$scope.times = [];
$scope.availableTimes = [];
$scope.fetchTimes = function() {
$scope.availableTimes = data;
}
$scope.fetchTimes();
MealSvc.get(function(res) {
$scope.times = res.dinnerTimes;
});
});
angular.module('MealService', []).factory('MealSvc', function($http) {
return {
get: function(response) {
response({
"name": "Second Tea",
"dinnerTimes": [46800000, 57600000]
})
}
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js" data-semver="2.2.0" data-require="jquery#*"></script>
<link data-require="chosen#*" data-semver="1.0.0" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/chosen/1.0/chosen.min.css" />
<script data-require="chosen#*" data-semver="1.0.0" src="//cdnjs.cloudflare.com/ajax/libs/chosen/1.0/chosen.jquery.min.js"></script>
<script data-require="chosen#*" data-semver="1.0.0" src="//cdnjs.cloudflare.com/ajax/libs/chosen/1.0/chosen.proto.min.js"></script>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link href="style.css" rel="stylesheet" />
<script data-semver="1.2.28" src="https://code.angularjs.org/1.2.28/angular.js" data-require="angular.js#1.2.x"></script>
<script src="app.js"></script>
</head>
<body>
<div class="container" ng-app="MealApp" ng-controller="MealCtrl">
<div class="row">
<select data-placeholder="Select Dinner Time" multiple class="chzn-select" chosen ng-model="times" ng-options="times.value as times.name for times in availableTimes"></select>
</div>
</div>
</body>
</html>

amCharts with AngularJS

I'm still strugling making work other libs with AngularJS because of it's differtent logic from other libs.
I need to visualize data with amCharts Stock, but there is nothing on the internet about these two wroking together.
How can i make this work with angularjs: http://jsfiddle.net/922JW/
var chart = AmCharts.makeChart("chartdiv", {
type: "stock",
"theme": "none",
pathToImages: "http://www.amcharts.com/lib/3/images/",
categoryAxesSettings: {
minPeriod: "mm"
},
dataSets: [{
color: "#b0de09",
fieldMappings: [{
fromField: "value",
toField: "value"
}, {
fromField: "volume",
toField: "volume"
}],
dataProvider: chartData,
categoryField: "date"
}],
panels: [{
showCategoryAxis: false,
title: "Value",
percentHeight: 70,
stockGraphs: [{
id: "g1",
valueField: "value",
type: "smoothedLine",
lineThickness: 2,
bullet: "round"
}],
stockLegend: {
valueTextRegular: " ",
markerType: "none"
}
},
{
title: "Volume",
percentHeight: 30,
stockGraphs: [{
valueField: "volume",
type: "column",
cornerRadiusTop: 2,
fillAlphas: 1
}],
stockLegend: {
valueTextRegular: " ",
markerType: "none"
}
}
],
chartScrollbarSettings: {
graph: "g1",
usePeriod: "10mm",
position: "top"
},
chartCursorSettings: {
valueBalloonsEnabled: true
},
periodSelector: {
position: "top",
dateFormat: "YYYY-MM-DD JJ:NN",
inputFieldWidth: 150,
periods: [{
period: "hh",
count: 1,
label: "1 hour",
selected: true
}, {
period: "hh",
count: 2,
label: "2 hours"
}, {
period: "hh",
count: 5,
label: "5 hour"
}, {
period: "hh",
count: 12,
label: "12 hours"
}, {
period: "MAX",
label: "MAX"
}]
},
panelsSettings: {
usePrefixes: true
}
});
Thanks.
I would create some basic directive (isolate scope) that receives chart settings and use as template:
<div id="container"></div>
In addition we can write several watchers to listen on user actions.
Here is working example How to use it:
(Its not based on your settings but you can use the same flow)
Demo Fiddle
Directive
myapp.directive('myElem',
function () {
return {
restrict: 'E',
replace:true,
scope: {
config: '='
},
template: '<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>',
link: function (scope, element, attrs) {
var chart = false;
var initChart = function() {
if (chart) chart.destroy();
var config = scope.config || {};
chart = new Highcharts.Chart(config);
if(config.loading) {
chart.showLoading();
}
};
initChart();
scope.$watch('config.loading', function (loading) {
if(loading) {
chart.showLoading();
} else {
chart.hideLoading();
}
});
scope.$watch('config.series[0].type', function (type) {
chart.series[0].update({type: type});
});
scope.$watch('config.series[0].dataLabels.enabled', function (enableDataLabels) {
chart.series[0].update({dataLabels: {enabled: enableDataLabels}});
});
}//end watch
}
}) ;
The usage:
<my-elem config="chartConfig"> </my-elem>
[EDIT]
Demo 2 FIddle
HTML
<div>
<my-elem ></my-elem>
</div>
JS
var myapp = angular.module('myModule', []);
myapp.directive('myElem',
function () {
return {
restrict: 'E',
replace:true,
template: '<div id="chartdiv" style="min-width: 310px; height: 400px; margin: 0 auto"></div>',
link: function (scope, element, attrs) {
var chart = false;
var initChart = function() {
if (chart) chart.destroy();
var config = scope.config || {};
chart = AmCharts.makeChart("chartdiv", {
"type": "serial",
"theme": "none",
"marginLeft": 20,
"pathToImages": "http://www.amcharts.com/lib/3/images/",
"dataProvider": [{
"year": "1950",
"value": -0.307
}, {
"year": "1951",
"value": -0.168
}, {
"year": "1952",
"value": -0.073
}, {
"year": "1953",
"value": -0.027
}, {
"year": "1954",
"value": -0.251
}, {
"year": "1955",
"value": -0.281
}, {
"year": "1956",
"value": -0.348
}, {
"year": "1957",
"value": -0.074
}, {
"year": "1958",
"value": -0.011
}, {
"year": "1959",
"value": -0.074
}, {
"year": "1960",
"value": -0.124
}, {
"year": "1961",
"value": -0.024
}, {
"year": "1962",
"value": -0.022
}, {
"year": "1963",
"value": 0
}, {
"year": "1964",
"value": -0.296
}, {
"year": "1965",
"value": -0.217
}, {
"year": "1966",
"value": -0.147
}, {
"year": "1967",
"value": -0.15
}, {
"year": "1968",
"value": -0.16
}, {
"year": "1969",
"value": -0.011
}, {
"year": "1970",
"value": -0.068
}, {
"year": "1971",
"value": -0.19
}, {
"year": "1972",
"value": -0.056
}, {
"year": "1973",
"value": 0.077
}, {
"year": "1974",
"value": -0.213
}, {
"year": "1975",
"value": -0.17
}, {
"year": "1976",
"value": -0.254
}, {
"year": "1977",
"value": 0.019
}, {
"year": "1978",
"value": -0.063
}, {
"year": "1979",
"value": 0.05
}, {
"year": "1980",
"value": 0.077
}, {
"year": "1981",
"value": 0.12
}, {
"year": "1982",
"value": 0.011
}, {
"year": "1983",
"value": 0.177
}, {
"year": "1984",
"value": -0.021
}, {
"year": "1985",
"value": -0.037
}, {
"year": "1986",
"value": 0.03
}, {
"year": "1987",
"value": 0.179
}, {
"year": "1988",
"value": 0.18
}, {
"year": "1989",
"value": 0.104
}, {
"year": "1990",
"value": 0.255
}, {
"year": "1991",
"value": 0.21
}, {
"year": "1992",
"value": 0.065
}, {
"year": "1993",
"value": 0.11
}, {
"year": "1994",
"value": 0.172
}, {
"year": "1995",
"value": 0.269
}, {
"year": "1996",
"value": 0.141
}, {
"year": "1997",
"value": 0.353
}, {
"year": "1998",
"value": 0.548
}, {
"year": "1999",
"value": 0.298
}, {
"year": "2000",
"value": 0.267
}, {
"year": "2001",
"value": 0.411
}, {
"year": "2002",
"value": 0.462
}, {
"year": "2003",
"value": 0.47
}, {
"year": "2004",
"value": 0.445
}, {
"year": "2005",
"value": 0.47
}],
"valueAxes": [{
"axisAlpha": 0,
"inside": true,
"position": "left",
"ignoreAxisWidth": true
}],
"graphs": [{
"balloonText": "[[category]]<br><b><span style='font-size:14px;'>[[value]]</span></b>",
"bullet": "round",
"bulletSize": 6,
"lineColor": "#d1655d",
"lineThickness": 2,
"negativeLineColor": "#637bb6",
"type": "smoothedLine",
"valueField": "value"
}],
"chartScrollbar": {},
"chartCursor": {
"categoryBalloonDateFormat": "YYYY",
"cursorAlpha": 0,
"cursorPosition": "mouse"
},
"dataDateFormat": "YYYY",
"categoryField": "year",
"categoryAxis": {
"minPeriod": "YYYY",
"parseDates": true,
"minorGridAlpha": 0.1,
"minorGridEnabled": true
}
});
};
initChart();
}
}
});
Use the module
https://github.com/natanielpaiva/angularAmChart
or
project example
https://github.com/natanielpaiva/angularAmChartSimples
Simple:
<amchart ng-model="objectLiveAmchart"> </amchart>
In Javascript:
$scope.objectLiveAmchart = { type:serial, ... }
I fount that the solution provided wasn't working for me.
In particular, the chart was not showing if the id in the template wasn't hardcoded.
It seemed like a problem with the AmCharts.makeChart() function that was't able to find the chardiv_idin the DOM.
I found that putting the initChart()function inside a scope.$watch('element') (after attaching elementto the scope in the linking function) was the right solution for me.
I think this is because after the element is created (so after the watch is called) is present and visible in the DOM, so the AmChart function can see it and render the chart correctly.
Hope this helped someone!

Categories

Resources