ext js 4 column chart bug? series remain visible when I hide them - extjs

Feeling I had not enough control over the chart if I had used a grouped column chart, I made my own version by just adding different series to the chart. After all the store, the number of series, their colors and such all need to be set dynamically and not hard coded. So basically this is what I have:
chart = Ext.create("Ext.chart.Chart", {
store: dataStore,
axes: dynamicAxes,
series: series
});
I leave out the not interesting stuff such as width, height of the chart etc.
now I have a method whichs returns a series object. This is added to the series array mentioned in the code above. The function has a "item" object parameter and also an idx param which is the index of the item object from the array it comes from, and a max param which is the size of the item array
the function returns something like this:
var w = (typeof (max) !== "undefined" && max !== null) ? this._getWidthByMax(max) : 30;
return {
type: "column",
axis = "left",
xField = "timestamp",
yField = item.id, // store field name equals the id of the item object
style = { stroke: colorCode, "stroke-width": (item.isDefault) ? 2 : 1, fill: colorCode },
width = w,
renderer = function (sprite, rec, attr, bix) {
var nx = idx * w;
return Ext.apply(attr, { translation: { x: nx} });
}
}
now this works fine for the number of columns I want to have. That can be one, two, three... up to seven currently.
However, if I want to hide a series, the following call doesn't work:
chart.series.getAt(idx).hideAll();
while it does work if I render my chart as a line chart.
is this a bug in Ext-js 4 or is it because of how I rendered the series for my column chart?

since nobody has replied to my question and I have found a solution in the meantime, I might as well answer my own question...
the problem occurred in Ext Js 4.0.7.
With version 4.1 RC 2 the hideAll behaved correctly.
So the solution, for anyone who would have the same problem, is to upgrade to 4.1 RC 2 or newer.

Related

Highcharts conditionally disable marker on hover

New to highcharts - I've got a chart that I have markers disabled on series
plotOptions: {
series: {
marker: {
enabled: false
}
}
},
which is great for the drawing of the lines, but, when I hover over the chart the markers are there. this is good, however, I do not want the marker to be present if the y value on the xAxis is 0 (empty) but I do want them when the y value on the xAxis is greater than one.
I was able to do this before by just setting the y value to null, disabling hover for that series, but the nulls present on this series - drawn as a stacked areaspline graph causes the spline to get drawn improperly (no spline, jagged edges when using the connectNulls: true option in series.
So how do I, and/or can I, conditionally disable a marker on hover based on the y value on an xAxis?
I have been looking at wrapping highcharts prototypes, which I am already doing to control some crosshair behavior drawCrosshair(): https://www.highcharts.com/docs/extending-highcharts/extending-highcharts but I can't seem to find anything that controls the drawing of the markers at that level
A very static approach to this is simply addressing each point with Y-value of 0. Then you could disable the hover-marker for each of these. One such point would look like this (JSFiddle demo):
{
y:0,
marker:{
states:{
hover:{
enabled:false
}
}
}
}
And used in a series:
series: [{
marker: {
enabled: false
},
data: [3, {y:0, marker:{states:{hover:{enabled:false}}}}, 3, 5, 1, 2, 12]
}]
As you can see, it's not pretty, but might help those who need an ad-hoc solution.
A dynamic approach to this is intercepting the setState-function of the Point.
For example, wrapping it and preventing the handling if the y-value is 0:
(function (H) {
H.wrap(H.Point.prototype, 'setState', function (proceed, state, move) {
if(this.y === 0) return;
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
});
}(Highcharts));
See this JSFiddle demonstration of it in action.

How can the numbercolumn in EXTjs 3.4 grid to display indian number format?

How can the numbercolumn in EXTJS 3.4 grid be formatted to display indian number format?
Eg: 45,78,895.45
One way you can do it is not ideal but you can override the Ext.grid.RowNumberer and tweak you rowNumber using javascript so that it returns in Indian number style. To do that we will use myNumString.toLocaleString('en-In'); method. I have created the function already for you. Here is the Example(fiddle). please mark this as answered if this solved your problem so that others can benefit from it. If something doesn't look right then please comment. Please look at the function below:
Ext.override(Ext.grid.RowNumberer, {
renderer: function(value, metaData, record, rowIdx, colIdx, store) {
var rowspan = this.rowspan;
if (rowspan) {
metaData.tdAttr = 'rowspan="' + rowspan + '"';
}
metaData.tdCls = Ext.baseCSSPrefix + 'grid-cell-special';
//return store.indexOfTotal(record) + 1;
var incrementedRowId = rowIdx + 1; //doing +1 as row id starts from 0
var indianRowNumber = incrementedRowId.toLocaleString('en-In');
return indianRowNumber;
}
});
Probably the better way is to write your own locale file for India (that's if they don't supply their own, though I can't see one). Have a look for the locale folder in your Ext framework download and copy the style of the file.
This can be achieved by using the renderer function. This way your store value woldn't have ',' but your grid appearance will. First things first ext stores numbercolumn as a string so we will use parseInt function to convert it to int and then we will use myNum.toLocaleString('en-In') this function will help us convert the number to Indian number string. Take a look at this example(fiddle) for better explanation. So basically whichever grid column value you want to show as Indian number just add the following function while declaring the grid column:
`header: "Indian Number Column",
dataIndex: 'currency',
flex: .5,
sortable: true,
renderer: function (val, metaData, r){
return parseInt(val).toLocaleString('en-In');
}`
Things you need to make sure are:
Don't forget to use parseInt or parseFloat as toLocaleString only works on numbers and ext stores numbercolumn value as a string
The value of the column is always a number so the parseInt doesnt fail
Bonus hint:
If you are dealing with currency and you want to add the Indian currency symbol and also want to round the decimal value then use the following code instead:
`header: "Indian Number Column",
dataIndex: 'currency',
flex: .5,
sortable: true,
renderer: function (val, metaData, r){
return parseFloat(val).toLocaleString('en-In', {
maximumFractionDigits: 2,
style: 'currency',
currency: 'INR'
});
}`

d3 line chart data point is cropped from min and max domain values

i am working on d3 charts with react and new on both react and d3. The issue i am trying to solve is;
I have a line chart and i have useInteractiveGuideline enabled, so when i hover over the graph, i can see what my value is on that point(with a circle on the line). The problem is; for the y axis values that are close to min or max grid lines, the data point is cropped just from the edge domain values and becomes an half circle.
line chart with cropped data points
I need some sort of padding to see the whole point on edges.
Is there any way to do that other than changing the domain values? I don't wanna change the domain values since my data is dynamic and can reach to very big numbers, so it may not be stable.
nv.addGraph(() => {
let chart = nv.models.lineChart()
.padData(true)
.noData('')
.margin({ "top": 20, "right": 20, "bottom": 20, "left": 20 })
.yDomain([0, max])
.useInteractiveGuideline(true);
chart.xAxis
.showMaxMin(false)
.ticks(5)
.tickFormat((d) => {
return ticks[d]
})
chart.yAxis.tickFormat((d) => {
return d;
})
d3.select('#chart')
.datum(chartData)
.transition().duration(700)
.call(chart);
return chart;
});
I've added below line and issue is solved
chart.lines.clipEdge(false);

jsDevExpress : dxTextArea - How to get the text area value when onFocusOut?

I am using jsDevExpress together with AngularJS, Is there a way to get the value of dxTextArea when user leave the widget? I know to do this using onValueChanged: function (ovc) {} but i am particularly interested the onFocusOut
$('<div/>').dxTextArea({
value: "",
height: 90,
valueChangeEvent: "change",
onFocusOut: function (ofo) {
?? ofo.value // not found
}
The textarea is repeated per record inside in a column using dxDataGrid.

angular-nvd3 content percentage in tooltip

I am looking into ways I can display the percent of a slice of pie compared to the current graph in the tooltip.
First I tried looking for something similar to chart.labelType: 'percent' but it looks like there is no such option.
What I am trying to do now is calculate the percentage inside chart.tooltip.contentGenerator according to documentation the function should be passed 5 arguments function (key, x, y, e, series) -> String however I am only receiving the first argument.
I am using angular 1.5.0, d3 3.5.16, nvd3 1.8.2, and angular-nvd3 1.0.5.
What is the best practice for displaying the percentage in the tooltip?
EDIT: You brought up a great point that I didn't account for, that the total (and thus the percentage portion of each pie segment) will change when you remove segments from the pie. Looked into how to account for this, and I discovered you can monitor the chart for a stateChange, and configure what happens when this event is dispatched.
So, what I've done is to update the total when that event is fired by filtering out whatever values are disabled:
chart: {
...,
dispatch: {
stateChange: function(e) {
total = _.reduce(_.filter($scope.data, function(value) {
return !value.disabled;
}), function(result, value, key) {
return result += parseFloat(value.y);
}, 0);
console.log(total);
}
},...
};
I've updated the example pie chart plunker with the new code, but everything else remained the same, except that I added in each key and the updated total into the tooltip so you can verify that it's working. But you'll still initialize the total value when the chart first loads:
var total = _.reduce($scope.data, function(result, value, key) {
return result += parseFloat(value.y);
}, 0);
...And use the chart.tooltip.contentGenerator method to customize the tooltip message, which you can set up to return something like this:
tooltip: {
contentGenerator: function (key, x, y, e, series) {
return '<h4>' + ((key.data.y / total) * 100).toFixed(2) + '% of total</h4>';
}
}
Hope that helps!

Resources