tooltip to hide the data based on user selection - javascript

I am working on angularjs googlecharts. when user click on legend, corresponding data on the chart is hidden. Issue is with the tooltip. When user click on legend Laptop(blue color) and mouseover on the any of the bar in the chart,the data on the tooltip which shows Laptop should be hidden, but the tooltip is showing information of Laptop also. The same is working when user click on Desktop Legend and mouseover on the bar, the data on the tooltip which shows Desktop is hidden.
Could not able to trace the issue, any suggestion on how to hide the tooltip information displaying Laptop information when user selects the Legend Laptop to hide laptop information.
Please find the demo here
js code:
angular.module('myApp', ['googlechart'])
.controller('myController', function($scope) {
var colorIndex = 0,
chart1 = {};
chart1.type = "ColumnChart";
chart1.displayed = false;
chart1.data = {
"cols": [{
id: "month",
label: "Month",
type: "string"
}, {
id: "laptop-id",
label: "Laptop",
type: "number",
colorIndex: colorIndex++
}, {
role: "tooltip",
type: "string",
p: {
'html': true
}
}, {
id: "desktop-id",
label: "Desktop",
type: "number",
colorIndex: colorIndex++
}],
"rows": [ {
c: [{
v: "Jan"
}, {
v: 13
},{
v: "laptop tooltip bar1"
}, {
v: 1,
f: "1 unit (Out of stock this month)"
}]
} ,{
c: [{
v: "February"
}, {
v: 13
},{
v: "laptop tooltip bar2"
}, {
v: 1,
f: "1 unit (Out of stock this month)"
}]
}, {
c: [{
v: "March"
}, {
v: 24
},{
v: "laptop tooltip bar3"
}, {
v: 5
}]
}]
};
chart1.options = {
"title": "Sales per month",
"colors": ['#0000FF', '#009900'],
"defaultColors": ['#0000FF', '#009900'],
focusTarget: 'category',
"isStacked": "true",
"fill": 20,
"displayExactValues": true,
tooltip: {textStyle: {fontName: '"Arial"', bold: "true", fontSize: "14"}},
"vAxis": {
"title": "Sales unit",
"gridlines": {
"count": 10
}
},
"hAxis": {
"title": "Date"
}
};
chart1.view = {
columns: [0, 1, 2,3]
};
$scope.myChart = chart1;
var hidden = [];
$scope.reset = function() {
for (var i = 0; i < hidden.length; i++) {
var hiddenCol = hidden[i];
$scope.myChart.view.columns[hiddenCol] = hiddenCol;
$scope.myChart.options.colors[hiddenCol - 1] = $scope.myChart.options.defaultColors[hiddenCol - 1];
}
hidden = [];
};
$scope.seriesSelected = function(selectedItem) {
if (selectedItem.row === null) {
var col = selectedItem.column,
colIndex = hidden.indexOf(col),
colorIndex = chart1.data.cols[col].colorIndex;
if (hidden.length === ($scope.myChart.view.columns.length - 3) && colIndex == -1) {
window.alert("One seies of data should be available all time");
}
else{
if(colIndex == -1){
hidden.push(col);
}
else{
hidden.splice(colIndex, 1);
}
if ($scope.myChart.view.columns[col] == col) {
$scope.myChart.view.columns[col] = $scope.myChart.data.cols[col];
$scope.myChart.options.colors[colorIndex] = '#CCCCCC';
}
else {
$scope.myChart.view.columns[col] = col;
$scope.myChart.options.colors[colorIndex] = $scope.myChart.options.defaultColors[colorIndex];
}
}
}
};
});

Related

add line bar to Associative array Bar

here is my associative array data for chart.js
i try to add line chart inside bar chart.
but i'm confuse how to add new chart inside it.
since my datasets is Array
const tmp_orders = [
{
"type": "import",
"year": 2020,
"total": 1
},
{
"type": "import",
"year": 2019,
"total": 0
},
{
"type": "import",
"year": 2018,
"total": 0
},
{
"type": "export",
"year": 2020,
"total": 0
},
{
"type": "export",
"year": 2019,
"total": 0
},
{
"type": "export",
"year": 2018,
"total": 0
}
],
const res = [];
const result = tmp_orders[0].map(function(obj) {
var tmp = []
Object.entries(obj).map(function([key, value]) {
tmp[key] = value
})
res.push(tmp)
});
console.log(res)
// get order type and sort
const types =[...new Set(res.map(v => v['type']))].sort();
// get order year and sort
const years =[...new Set(res.map(v =>v['year']))].sort();
// set order color and sort
const colors = ['#ff0000', '#6383ff'];
// data for target order chart
const target_data = types.map(type => ({
label: type,
data: years.map(year => {
const value = res.find(v => v['type'] == type && v['year'] == year );
return value['total'];
}),
backgroundColor: function(){
if(type === 'import'){
return '#ff0000'
}else if(type === 'export'){
return '#6383ff'
}
}
}))
const targetOrderCtx = $('#chart_target_order'),
optionOrder = {
maintainAspectRatio: false,
responsive: true,
title: {
display: true,
text: 'Target Order',
fontSize: 18,
fontColor: '#6383ff'
},
legend: {
display: true,
position: 'bottom'
},
animation: {
animateScale: true,
animateRotate: true
}
}
// create Target Order Chart
var chart_target_order = new Chart(targetOrderCtx, {
type: 'bar',
data: {
labels: years,
datasets: target_data
},
options: optionOrder
});
if you look inside my datasets
you will find out that's Array.
mostly i find some solution like add line chart insie datasets, but it seems impossible for me.
EDIT 1
here is the result that i want.

Json data not able to display as a graph using sigma.js

I'm using this code to display JSON file data as a graph but it is not displaying anything.
How to display this JSON data using sigma.js in graph form.
Any pointers would be appreciated!
Code
var data = {
"UniversalWord": {
"UniversalWord": [{
"uw_id": 1,
"HeadWord": {
"word": "aare"
},
"Restriction": {
"SemanticRelations": {
"feat": [{
"att": "restriction_type",
"value": "iof"
},
{
"att": "target",
"val": " "
}
]
}
},
"NLDescription": {
"Gloss": {
"feat": {
"att": "Description",
"val": "\"A RIVER IN NORTH CENTRAL SWITZERLAND THAT RUNS NORTHEAST INTO THE RHINE\""
}
},
"Lemma": {
"feat": {
"att": "word",
"val": "aare"
}
},
"Example": {
"feat": {
"att": "description",
"val": "\"\""
}
}
},
"MetaInfo": {
"Frequency": {
"freq": ""
},
"UWSource": {
"Source_id": "WORDNET"
}
}
}]
}
}
// these are just some preliminary settings
var g = {
nodes: [],
edges: []
};
// Create new Sigma instance in graph-container div (use your div name here)
s = new sigma({
graph: g,
container: 'graph-container',
renderer: {
container: document.getElementById('graph-container'),
type: 'canvas'
},
settings: {
minNodeSize: 8,
maxNodeSize: 16
}
});
// first you load a json with (important!) s parameter to refer to the sigma instance
sigma.parsers.json(
//'test.json',
data,
s,
function() {
// this below adds x, y attributes as well as size = degree of the node
var i,
nodes = s.graph.nodes(),
len = nodes.length;
for (i = 0; i < len; i++) {
nodes[i].x = Math.random();
nodes[i].y = Math.random();
nodes[i].size = s.graph.degree(nodes[i].id);
nodes[i].color = nodes[i].center ? '#333' : '#666';
}
// Refresh the display:
s.refresh();
// ForceAtlas Layout
s.startForceAtlas2();
}
);
.link {
fill: none;
stroke: #000;
}
.node {
stroke: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/sigma.js/1.2.0/sigma.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sigma.js/1.2.0/plugins/sigma.parsers.json.min.js"></script>
<div id="graph-container"></div>

Kendo ui grid: change field type depending in the row

I'm having a issue that I dont know how to afford. I have a kendo grid which is being poblated with a json file.
The issue is that in the json file there is a field that has a different type in different elements.
I'll explain myself with an example:
"listaPreguntas": [
{
"idPregunta": 1126,
"idTipificacion": 1712,
"tipoPregunta": "E",
"pregunta": "¿DE QUE COLOR ES?",
"numeroOrden": 2,
"respuestasPosibles": [
{
"idRespuestaPosible": 1066,
"respuestaPosible": "HOSPITAL"
},
{
"idRespuestaPosible": 1068,
"respuestaPosible": "AMBULATORIO"
},
{
"idRespuestaPosible": 1070,
"respuestaPosible": "CENTRO SALUD"
},
{
"idRespuestaPosible": 1072,
"respuestaPosible": "UNIDAD MOVIL"
},
{
"idRespuestaPosible": 1074,
"respuestaPosible": "UNIDAD DONACION"
},
{
"idRespuestaPosible": 1076,
"respuestaPosible": "UNIDAD MOVIL (UVI)"
}
],
"idTipoEnumerado": 1
},
{
"idPregunta": 1150,
"idTipificacion": 1712,
"tipoPregunta": "T",
"pregunta": "¿cuantas personas?",
"numeroOrden": 1,
"respuestasPosibles": null,
"idTipoEnumerado": 0
},
{
"idPregunta": 1152,
"idTipificacion": 1712,
"tipoPregunta": "F",
"pregunta": "¿Mayores?",
"numeroOrden": 3,
"respuestasPosibles": null,
"idTipoEnumerado": 0
}
You can see three objects in the json file, the first object has a type "E" and has six possible values, the second object has a type "T" (Text) and the last one is a boolean.
What i need is to show in the grid a column which type change depending on the type of the json. I need to have a text value in some cases, a checkbox and a dropdownbox.
I hope you could understand me.
Thanks in advance.
Here is example for custom editor from http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-columns.editor
$("#grid").kendoGrid({
columns: [ {
field: "name",
editor: function(container, options) {
var input = $("<input/>");
input.attr("name", options.field);
input.appendTo(container);
if(options.model.tipoPregunta == 'E')
{
input.kendoDropDownList( ... );
}
if(options.model.tipoPregunta == 'T')
{
....
}
if(options.model.tipoPregunta == 'F')
{
....
}
}
} ],
editable: true,
dataSource: [ { name: "Jane Doe" }, { name: "John Doe" } ]
});
options.model is a row dataItem
You just need to create a template for your column in your grid config:
columns: [{
field: "respuestasPosibles",
template: function(e){
if ( (e.tipoPregunta === 'E') && $.isArray(e.respuestasPosibles) ){
var st = '';
$.each(e.respuestasPosibles, function(i, a){
st += a.respuestaPosible + '(' + a.idRespuestaPosible + ')<br>';
});
return st;
}
else{
// The cell will be empty
return '-';
}
}, ....
]

How to create a new div dynamically everytime a element in data is introduced

I have a data coming from a VM that has several block devices. Every block device is represented with a a line charts that where created using c3.js that read Bytes_Read and Bytes_Written in the dataset and chart it in realtime. But I am struggling with the issue when there are new block devices introduced in dataset it does not create a new chart. What would be the best way to achieve this using JavaScript.
Sample of my dataset
{
"devices": [
{
"Name": "bdev0",
"output": {
"IO_Operations": 0,
"Bytes_Read": 0,
"Bytes_Written": 0
}
},
{
"Name": "bdev0",
"output": {
"IO_Operations": 1,
"Bytes_Read": 2,
"Bytes_Written": 3
}
},
{
"Name": "bdev0",
"output": {
"IO_Operations": 5,
"Bytes_Read": 7,
"Bytes_Written": 8
}
},
{
"Name": "bdev1",
"output": {
"IO_Operations": 10,
"Bytes_Read": 20,
"Bytes_Written": 30
}
}
]
}
Updated dataset with a new device
{
"devices": [
{
"Name": "bdev0",
"output": {
"IO_Operations": 0,
"Bytes_Read": 0,
"Bytes_Written": 0
}
},
{
"Name": "bdev0",
"output": {
"IO_Operations": 1,
"Bytes_Read": 2,
"Bytes_Written": 3
}
},
{
"Name": "bdev0",
"output": {
"IO_Operations": 5,
"Bytes_Read": 7,
"Bytes_Written": 8
}
},
{
"Name": "bdev1",
"output": {
"IO_Operations": 10,
"Bytes_Read": 20,
"Bytes_Written": 30
},
{
"Name": "bdev2",
"output": {
"IO_Operations": 40,
"Bytes_Read": 50,
"Bytes_Written": 90
}
}
]
}
chart code
eon.chart({
pubnub : pubnub,
history : false,
channel : 'orbit5_volume',
flow : true,
debug: true,
generate : {
bindto : '#chart',
size: {
height: 180,
width: 500
},
data : {
x : 'x',
labels : true
},
axis : {
x : {
type : 'timeseries',
tick : {
format : '%H:%M:%S'
},
zoom: {
enabled: true
}
}
}
},
transform : function(m) {
for (var i in m.devices){
return { columns : [
['x', new Date().getTime()],
['Bytes Written', m.devices[i].output.Bytes_Read],
['Bytes Read', m.devices[i].output.Bytes_Written]
]
}
}
}
});
You're chart code transform loop is overwriting every data's key which is why you're only getting a couple values. If you use the i variable to give each piece of data a new key, it'll show up on the chart.
Try this transform function:
eon.chart({
transform : function(m) {
var obj = {columns: [
['x', new Date().getTime()]
]};
for (var i in m.devices) {
obj.columns.push(['Bytes Read ' + i, m.devices[i].output.Bytes_Read]);
obj.columns.push(['Bytes Written ' + i, m.devices[i].output.Bytes_Written]]);
}
}
return obj;
}
});

Column chart in Google Chart displays bar below min

Ok, I've been looking for something similar to what I'm experiencing online but I can't so I decided to ask around here for some advise to solve my issue.
I'm using Angular Google chart and trying to create a column chart to display historical values for portfolio totals.
Code to create chart
$scope.createPortfolioBalanceChart = function(){
var data = JSON.parse($scope.portfolioChartData.rows.toJSON());
console.log(JSON.stringify($scope.portfolioChartData).replace(/\\/g,''));
var minValue = _.reduce(data.rows, function(memo, bal){
var value = bal.c[1].v;
return (value !== null && value < memo) ? value : memo;
}, Number.MAX_SAFE_INTEGER);
var maxValue = _.reduce(data.rows, function(memo, bal){
var value = bal.c[1].v;
return value > memo ? value : memo;
}, Number.MIN_SAFE_INTEGER);
var rangeBleed = (maxValue - minValue) * PortfolioBalanceChartConfig.rangeBleedPadding;
var chart = {};
chart.type = 'ColumnChart';
chart.data = data;
chart.options = {
'height': 300,
'fill': 20,
isStacked: false,
'vAxis':{
'baselineColor': 'none',
'gridlineColor': 'none',
'format': '$#,###',
'position': 'right',
'viewWindow' : {
'min': rangeBleed > 0 ? minValue - rangeBleed : 0, // if the range is 0 then start the graph from 0
'max': maxValue + rangeBleed
}
},
'displayExactValues': true,
'tooltip' : {
'trigger': true
},
'legend': {
'position': 'none'
},
'bar': {
'groupWidth': 30
},
'colors': ['#33b4e6', '#0675c2'],
};
chart.formatters = {
number : [{
columnNum: 1,
pattern: '$ #,##0.00'
},
{
columnNum: 2,
pattern: '$ #,##0.00'
}]
};
$scope.portfolioBalanceChart = chart;
};
Note:
minValue and maxValue above was calculated to add padding to the chart data.
$scope.portfolioChartData
{
"rows": {
"cols": [
{
"label": "Period",
"type": "string"
},
{
"label": "Balance",
"type": "number"
},
{
"role": "style",
"type": "string",
"p": {
"role": "style"
}
}
],
"rows": [
{
"c": [
{
"v": "Mar 2015"
},
{
"v": 68484.43
},
{
"v": ""
}
]
},
{
"c": [
{
"v": "Apr 2015"
},
{
"v": 68484.43
},
{
"v": ""
}
]
},
{
"c": [
{
"v": "May 2015"
},
{
"v": 68484.43
},
{
"v": ""
}
]
},
{
"c": [
{
"v": "Jun 2015"
},
{
"v": 68484.43
},
{
"v": ""
}
]
},
{
"c": [
{
"v": "Jul 2015"
},
{
"v": 68484.43
},
{
"v": ""
}
]
},
{
"c": [
{
"v": "Today"
},
{
"v": 600000
},
{
"v": ""
}
]
}
]
},
"cols": [
{
"label": "axis",
"type": "string"
},
{
"label": "Portfolio",
"type": "number"
}
]
}
stackoverflow is preventing me to post image so here's a sample image of the chart constructed above:
http://postimg.org/image/gtnq81au3/
OK, I've solved the issue at last. There seems to be some property hiding in the google chart docs that enables you to set what should be the baseline. This is different from what the viewWindow.min is. I added it below the viewWindow property.
$scope.createPortfolioBalanceChart = function(){
var data = JSON.parse($scope.portfolioChartData.rows.toJSON());
var minValue = _.reduce(data.rows, function(memo, bal){
var value = bal.c[1].v;
return (value !== null && value < memo) ? value : memo;
}, Number.MAX_SAFE_INTEGER);
var maxValue = _.reduce(data.rows, function(memo, bal){
var value = bal.c[1].v;
return value > memo ? value : memo;
}, Number.MIN_SAFE_INTEGER);
var rangeBleed = (maxValue - minValue) * PortfolioBalanceChartConfig.rangeBleedPadding;
var chart = {};
chart.type = 'ColumnChart';
chart.data = data;
chart.options = {
'height': 300,
'fill': 20,
isStacked: false,
'vAxis':{
'baselineColor': 'none',
'gridlineColor': 'none',
'format': '$#,###',
'position': 'right',
'viewWindow' : {
'min': rangeBleed > 0 ? minValue - rangeBleed : 0, // if the range is 0 then start the graph from 0
'max': maxValue + rangeBleed
},
'baseline': rangeBleed > 0 ? minValue - rangeBleed : 0 // set to be the same as min to prevent bar overlapping label below it
},
'displayExactValues': true,
'tooltip' : {
'trigger': true
},
'legend': {
'position': 'none'
},
'bar': {
'groupWidth': 30
},
'colors': ['#33b4e6', '#0675c2'],
};
chart.formatters = {
number : [{
columnNum: 1,
pattern: '$ #,##0.00'
},
{
columnNum: 2,
pattern: '$ #,##0.00'
}]
};
$scope.portfolioBalanceChart = chart;
};

Categories

Resources