Event Handling in nvd3 - angularjs

I am using nvd3 and trying to add event handling while clicking on the chart. But I face some problems while implementing it and I am not able to get a solution due to lack of documentation of nvd3. I followed this link, but I still get the following error in the console:
ReferenceError: chart is not defined
Can anyone tell me what I am missing or any best solution for the event handling in nvd3.

Probably your problem is the name of the graph variable;
I make a fiddle for you.
In my example, "chart" is the name of the graph variable. Check out that also in your case it's the same.
var chart = nv.models.multiBarChart();
Anyway, with the fiddle you can see the full code. If you click on an item, you can see the messages in console.
http://jsfiddle.net/g952qb5c/

As suggested by Giordano, I looked for the name of the graph and the dispatch events. And then I have added these event listener in the options like this.
Note: This solution worked for the nvd3 and angular.
$scope.options2 = {
chart: {
type: 'pieChart',
height: 500,
x: function(d){return d.key;},
y: function(d){return d.y;},
showLabels: true,
duration: 500,
labelThreshold: 0.01,
labelSunbeamLayout: true,
legend: {
margin: {
top: 5,
right: 35,
bottom: 5,
left: 0
}
},
pie:{
dispatch: {
elementClick : function(e){
console.log('element: ' + e.value);
console.log(e);
}
}
}
}
};
Hope this will help to others also.

Related

X axis title is disappearing after first time, when reloading rGrpah chart on same div

I am using rGraph to draw the chart. it is working fine for the first time. when trying to generate the graph with different input data for the second time, without refreshing the page. The graph is generating fine, but the x-axis title is disappearing. can anyone help me with this?
FYI: I am making that div empty, before generating the graph.
Attaching image:
1:
In the first image, you can see the Date.
Here you don't see the Date. when I change the input data and tried to generate the chart.
if(document.getElementById(chartID)){
RG.ObjectRegistry.Remove(document.getElementById(chartID));
}
var barGraph = new RGraph.Bar({
id: chartID,
data: chartData,
options: {
variant: '3d',
variantThreedAngle: 0.05,
colorsStroke: 'rgba(0,0,0,0)',
colors: chartColorArr,
marginTop: 35,
marginLeft: 45,
marginRight: 15,
marginBottom: 85,
xaxisLabels: x_axis_label_Arr,
shadowColor:'#ccc',
shadowOffsetx: 3,
backgroundGridColor: '#eee',
xaxisScaleZerostart: true,
axesColor: '#f2f2f2',
//yaxisScaleUnitsPost: 'H',
//title: 'User Sessions',
//key: [legendsTitle],
keyShadow: true,
keyShadowColor: '#ccc',
keyShadowOffsety: 0,
keyShadowOffsetx: 3,
keyShadowBlur: 15,
variantThreedXaxis : true,
variantThreedYaxis : true,
bevelled : false,
axes : true,
tooltips: chartTooltipArr,
tooltipsEvent : 'onmousemove',
xaxisTitle : **'Date',**
yaxisTitle : yAxisTitle,
xaxisTitleSize : legendFontSize,
yaxisTitleSize : legendFontSize,
xaxisLabelsSize : legendFontSize,
yaxisLabelsSize : legendFontSize,
yaxisTitlePos : 0.1,
colorsSequential : true,
}
});
barGraph.draw();
Thanks
By the looks of the 3D style and some other cues, you're using quite an old version. Here's two modern-style 3D charts:
https://www.rgraph.net/demos/bar-3d-effect-multi-row.html
https://www.rgraph.net/demos/bar-ajax.html
There's more examples in the download archive which are worth looking at.
As for the problem with your chart, I think the easiest solution would be to set the textAccessible option to false:
textAccessible: false,

angular nvd3 duration not affect pie chart

I want to make the transition/animation effect when selecting/unselecting items longer, I'm trying to set the duration parameter of nvd3 pie chart to be something long like 10 seconds (or 10000 ms) but it has no effect on the pie chart,
I tried changing the duration value and I also tried to add transitionDuration property,
$scope.options = {
chart: {
type: 'pieChart',
height: 500,
x: function(d){return d.key;},
y: function(d){return d.y;},
showLabels: true,
duration: 10000,
transitionDuration: 10000
}
};
You can see the following example: http://plnkr.co/edit/vtKWU0?p=preview
It looks like a bug in nvd3.
https://github.com/novus/nvd3/issues/1474#issuecomment-178333163
angular-nvd3 is a wrapper around nvd3.

nvd3 chart strange behavior with date range slider

While displaying nvd3 chart with Ajax requests, the charts are getting wired up. So I thought the problem is occurring due to asynchronous call delays (may be the chart is displaying before the full data is loaded, etc). So I have used promises, but still I am getting the same problem. Please see the plunker http://plnkr.co/edit/AcIpmki7GNvcoT6Z38Pm?p=preview.
If you change the date range slider, the main chart won't display properly. I am not sure where the problem is? After searching some of the posts in forum, I have come across some thing like gaps in the time series, is it due to that? If that is the case, how can I fix that time series gap issue? I searched nvd3 website, but I don't find any documentation regarding to fill up the gaps in time series data. Some of the forum posts suggests to use c3.js instead nvd3, but I don't know is it really worth to shift to c3.js? Within my experience I feel nvd3 are the best and I don't feel like leaving nvd3.
If nvd3 website provides more samples with real time series data and documentation on some of the common issues like filling gaps in time series, sorting the data, etc it will be really helpful for the beginners.
As my project release dates are nearing, I am not sure what to do now ? Shifting to c3.js is the worst option for me. I have attached the error screen shot too from the same plunker.
I feel there is no problem with the sorting that I am doing with my json data:
angular.forEach($scope.data, function(
series, index) {
series.values.sort(function(a, b) {
return a.x - b.x;
});
});
Couple of issues for you to look at:
I agree with shabeer90, the data is funky. You have multiple values occurring at the same time.
Your sort is correct, but where you have it in your code doesn't work...try adding it inside the response of the ajax call (right after setting $scope.data = data).
Also, you need to make the changes that I outlined in another question (to nvd3 in the lineWithFocusChart model).
Accessing the xScale is a little more tricky...on this chart you need to go through the lines:
$scope.options = {
chart: {
type: 'lineWithFocusChart',
height: 450,
margin : {
top: 20,
right: 20,
bottom: 60,
left: 40
},
transitionDuration: 500,
lines : { // <-- add this
xScale : d3.time.scale()
},
lines2 : { // <-- add this too
xScale : d3.time.scale()
},
xAxis: {
ticks : d3.time.months, <-- add the time interval
axisLabel: 'X Axis',
tickFormat: function(d){
return d3.time.format('%d/%m/%y')(new Date(d))
}
},
x2Axis: {
tickFormat: function(d){
return d3.time.format('%d/%m/%y')(new Date(d))
}
},
yAxis: {
axisLabel: 'Y Axis',
tickFormat: function(d){
return d3.format(',.2f')(d);
},
rotateYLabel: false
},
y2Axis: {
tickFormat: function(d){
return d3.format(',.2f')(d);
}
}
}
};

ExtJS Window Position Changing On Resize

Using ExtJS 4, I have the following window:
var mainWin = Ext.create('Ext.Window',{
title: 'IE Screwup Illustration',
id: 'MAINWIN',
constrain: true,
constrainTo: 'appdiv',
x: 0,
y: 0,
width: '100%',
height: 518,
moveable: false,
closable: false,
layout: {
type: 'border',
padding: 3
},
renderTo: Ext.Element.get('appdiv'),
}).show();
Note the rendering to an element called "appdiv", which is a element whose style is shown below:
#appdiv {
position: absolute;
left: 10px;
width: 90%;
height: 520px;
border: 1px solid;
overflow: hidden;
border-color: #000000;
}
There is no problem rendering the window. It appears within the appdiv without problems with a nice border around it.
The problem begins when I resize the browser. It appears that the window attempts to center itself on the screen instead of within the appdiv DIV. This causes it to be displaced within the DIV so that it renders below and to the right of the left corner.
I have tried various tricks, including an attempt to reposition the window when it resizes. Nothing seems to work and I cannot think of anything else.
Could someone please give some idea how to keep this window within its DIV when a browser is resized? Thanks...
I have created a JS Fiddle to illustrate how I usually solved the problem in my projects.
The solution is to listen to the resize event of the Component over which you would like to center your window, and then calculate your window's new position. In my example this component was the viewport.
Here is the listener, that gets the job done:
viewPort.on('resize', function(vp, width, height) {
var me = this,
winWidth = me.getWidth(),
winHeight = me.getHeight(),
left = (width -winWidth) / 2,
top = (height -winHeight) / 2;
me.setPosition(left, top);
}, mainWin);
I found the answer to the problem. It turns out to be a question of timing.
It didn't make sense that the setPosition() method suggested by Matyas seemed to be ignored, so I checked the "move" event. Apparently, when an Ext window is rendered to a <div>, it receives move events after resize events. I do not know why (perhaps experts in ExtJS internals can help here?).
So instead of doing the calculations shown in Matyas' resize listener, I created a move listener in mainWin. Mine was somewhat simpler, since I wanted the window to stay put at the <div>'s upper left corner:
listeners: {
move: function(theWin,xP,yP,theOp) {
if((xP != 0) || (yP != 0)) {
theWin.setPosition(0,0);
}
}
This way, any time the browser moved the window to a position other than where I wanted it, I would set it back. This solved the problem.
Thanks for all who responded to this question (including the comments). Without those responses, I would not have had the clues I needed to solve this problem.
Try this:
Ext.EventManager.onWindowResize(function()
{
mainWin.doComponentLayout();
}, this, {buffer: 1});
Ext.EventManager.onWindowResize(function() {
if(mainWin.isVisible()) {
mainWin.center();
}
}, this, {buffer: 1});

How can I add labels to either end of a ExtJS Slider control?

I am using ExtJS 3.3 but this might be relevant to other versions as well.
I am using a Slider control in an ExtJS-based UI. I have a tooltip set up to show the value as you drag it, as per the "Slider with Tip" example here: http://dev.sencha.com/deploy/ext-3.3.1/examples/slider/slider.html
It seems to me to be quite poor UX to have a slider with no indication of what the values are (or in this case not until you start sliding it). I would like to add labels to either end to show the range the slider is representing. Something like this:
So, of course, I'm wondering: Is this possible with the standard control itself? (I looked in the docs, but nothing jumped out at me)? or is there a neat way of achieving this?
Here is I went about to do it:
var tip = new Ext.slider.Tip({
getThumbText: this.getThumbText,
getText: function (thumb) {
return '<b>' + this.getThumbText(thumb.value) + '<b>';
}
});
this.timeSliderLabel = new Ext.form.Label({
text: Nipendo.Localization.HistorySlider + ': ',
style: 'margin:3px 5px 0px 5px;'
});
this.timeSlider = new Ext.Slider({
width: 214,
value: 1,
increment: 1,
minValue: 1,
maxValue: 13,
plugins: tip
});
this.timeSlider.on('change', function (slider, newValue, thumb) {
this.timeSliderHintLabel.setText(this.getThumbText(thumb.value), false);
this.onSearchClick();
}, this);
this.timeSliderHintLabel = new Ext.form.Label({
html: String.format('(1 {0})', Nipendo.Localization.OneMonthBack),
style: 'margin:3px 5px 0px 5px;'
});
UPDATE:
The layout could be used like this:
config = config.apply({
layout: 'column',
defaults: {
layout: 'form'
},
items: [
this.timeSliderLabel,
this.timeSlider,
this.timeSliderHintLabel
]
}, config)
Where getThumbText is a helper method I use to get the correct label value.

Resources