Infragistics igDataChart dynamic binding - javascript

I have a igdatagrid column chart in my application . The requirement is to update the chart as per the change in data. the chart also has Customtooltip on the bars which can be seen on hover . now when the data changes ,chart is rendered if tooltip is not used but when i use tooltip it shows error .
initially while loading my page everything works fine but after updating the datasource it shows some error
this is my javascript code
$("#chart").igDataChart({
width: "98%",
height: "350px",
dataSource: jsonObj,
title: "Sector Comparison",
windowResponse: "immediate",
axes: [{
name: "xAxis",
type: "categoryX",
label: "xValue",
labelTopMargin: 5,
gap: 5
}, {
name: "yAxis",
type: "numericY",
minimumValue: 0,
maximumValue: 109,
labelLocation: "outsideRight",
majorStrokeThickness: 2,
majorStroke: "#0856a7",
minorStroke: 'black',
minorInterval: 10,
interval: 50,
formatLabel: function (value) {
if (value == 50) {
return "Medium value";
}
},
}, {
name: "yAxis1",
type: "numericY",
title: "Rank",
minimumValue: 0,
maximumValue: 109,
labelLocation: "outsideLeft",
interval: 10,
formatLabel: function (value) {
return value;
},
}],
series: [{
name: "series1",
type: "column",
isHighlightingEnabled: true,
isTransitionInEnabled: true,
xAxis: "xAxis",
yAxis: "yAxis",
valueMemberPath: "value",
showTooltip: true,
remove: true,
isCustomCategoryStyleAllowed: true,
}],
assigningCategoryStyle: function (e, ui) {
var startIndex = ui.startIndex;
var endIndex = ui.endIndex;
var items =ui.getItems(startIndex,endIndex);
var color = ui.fill;
for (var i = 0; i < items.length; i++) {
if (items[i].color) {
color = items[i].color;
}
}
ui.fill = color;
}
this is the code i write while binding tooltip initially
//get
var series = $("#chart").igDataChart("option", "series");
series[0].tooltipTemplate;
//Set
$("#chart").igDataChart("option", "series",
[{
name: "series1",
type: "column",
isHighlightingEnabled: true,
isTransitionInEnabled: true,
xAxis: "xAxis",
yAxis: "yAxis",
valueMemberPath: "value",
showTooltip: true,
isCustomCategoryStyleAllowed: true,
tooltipTemplate: "CustomTooltipTemplate",
}]
);
"CustomTooltipTemplate" is my custom tooltip template that works completely fine initially
when i get the new data after which i try to update chart with tooltip
series[0].tooltipTemplate;
show error in console as
Cannot read property 'tooltipTemplate' of undefined
and if i don't use custom template and just use property showTooltip
Cannot read property 'updateToolTip' of undefined is shown ,
is there any way i can use custom tootltip and dataSource dynamically.
i used to update the datasource i,e jsonObj .
i found the solution .
on updation of chart i overwrite the series and assign datasource to the chart and renderseries as below and it works
$("#chart").igDataChart({
series: [{
name: "series1",
type: "column",
isHighlightingEnabled: true,
isTransitionInEnabled: true,
xAxis: "xAxis",
yAxis: "yAxis",
valueMemberPath: "value",
isCustomCategoryStyleAllowed: true,
}],
});
$("#chart").igDataChart("option", "dataSource", jsonObj);
$("#chart").igDataChart("renderSeries", "xAxis", false);
$("#chart").igDataChart("renderSeries", "yAxis", false);
$("#chart").igDataChart("renderSeries", "yAxis1", false);

Related

How to update data from ajax call (chart.js)

I manage to generate a graph from an ajax call coming from a php file.
I want to modify this graphic from the selection of the customers field (chg_customer) via a drop-down list. My drop-down list works and shows the names of the customers. However, I cannot generate a new chart from this selection with the right number (count) corresponding to the right customer. Can you help me ? thank you
html :
<select id="filter">
<option>Tous</option>
</select>
<canvas id="graph4Canvas" style="height: 700px; width: 100%;"></canvas></select>
graph.js :
$(document).ready(function() {
$.ajax({
url: 'graph4.php',
type: 'GET',
dataType: 'json',
success: function(data) {
var chg_customer = [];
var count = [];
for (var i in data) {
chg_customer.push(data[i].chg_customer);
count.push(data[i].count);
}
var ctx = $('#graph4Canvas');
const barGraph = new Chart(document.getElementById('graph4Canvas'), {
type: 'bar',
data: {
labels: data.map(o => o.chg_customer),
datasets: [{
label: 'Clients',
data: data.map(o => o.count),
backgroundColor: "rgba(0, 0, 255, 0.5)",
yAxisID: 'Nombres',
xAxisID: 'Clients',
}]
},
options: {
scales: {
yAxes: [{
id: "Nombres",
ticks: {
beginAtZero: true,
stepSize: 1,
fontSize: 15,
},
scaleLabel: {
display: true,
labelString: 'Nombres'
},
gridLines: {
drawOnChartArea: false
},
}],
xAxes: [{
id: "Clients",
ticks: {
beginAtZero: true,
stepSize: 1,
fontSize: 10,
},
scaleLabel: {
display: false,
},
gridLines: {
drawOnChartArea: false
},
}],
},
title: {
display: false,
},
legend: {
display: false,
},
},
});
data.forEach(o => {
const opt = document.createElement('option');
opt.value = o.chg_customer;
opt.appendChild(document.createTextNode(o.chg_customer));
document.getElementById('filter').appendChild(opt);
});
$("#filter").change(function() {
//update data
});
There isn't a need to generate a new chart. Once the chart exists all you need to do is to edit the datasets and call the chart update function to re-render the chart.
e.g (example is using angular in my case but still should apply):
HTML:
<mat-select [(value)]="selectedFilter" (selectionChange)="filterStreamType()">
JS:
public filterStreamType() {
// code manipulates data....
this.chart.data.datasets = newData; // update our dataset so chart js can re-draw it
this.chart.update(); // This is a redundant call but I did a bad job here and mixed some things that should not be mixed and so
}
Also note that between V2 and V3 there have been breaking changes so this syntax may vary a bit depending on the version you use.

bind first property value of an array of object into chart.js

I have an array of object and this is how I assigned values into it.
$("#gridview").click(function () {
$("table tbody th").each(function () {
var k = $(this).text().trim();
keys.push(k);
});
$("table tbody tr").each(function (i, el) {
var row = {}
$.each(keys, function (k, v) {
row[v] = $("td:eq(" + k + ")", el).text().trim();
});
myData.push(row);
});
myData.shift()
myData.length = 10
console.log(myData);
});
This is how my array of object looks like in inspect element - console
how can I get the values of Region and bind it to the labels below:
new Chart(document.getElementById("chart"), {
type: 'horizontalBar',
data: {
labels: [I want to display all the region here],
datasets: [{
label: "Android",
type: "horizontalBar",
stack: "Base",
backgroundColor: "#eece01",
data: ["I want to display ios user here"],
}, {
label: "ios",
type: "horizontalBar",
stack: "Base",
backgroundColor: "#87d84d",
data: ["I want to display android user here"]
}]
},
options: {
scales: {
xAxes: [{
//stacked: true,
stacked: true,
ticks: {
beginAtZero: true,
maxRotation: 0,
minRotation: 0
}
}],
yAxes: [{
stacked: true,
}]
},
}
});
FYI I have tried myData[Region] but its not working
Guys, I have searched the solutions whole day, seems cant found, please help
You can set the labels using .map() method on myData array like:
data: {
labels: myData.map(d => d.Region),
....
},
EDIT:
You can create a new function and add all chart init code into it like:
function CreateChart() {
new Chart(document.getElementById("chart"), {
type: 'horizontalBar',
data: {
labels: myData.map(d => d.Region),
... you code here
},
...
});
}
CreateChart();
and then on gridview click, again call this CreateChart function in the end like:
$("#gridview").click(function() {
// all your code logic here
console.log(myData);
CreateChart();
});

Highcharts.js question: is it possible to keep some part of chart in visible area always, even if "overscoll" option is set

I need to show some empty space to far right of the chart. To do so I use "overscroll" option (https://api.highcharts.com/highstock/xAxis.overscroll). But if user zoom in chart and pans chart to far right there can be empty space without any part of candlestick chart displayed (https://screencast-o-matic.com/watch/cqnfFq3CII). Please advise is it possible to implement following chart behaviour and how to do so: to keep some part of chart in visible area always, even if "overscoll" option is set and user pans chart to the far right? Thanks!
Here is my code:
var ohlc = JSON.parse(ohlcStringified),
volume = JSON.parse(volumeStringified);
var interval = ohlc[ohlc.length - 1].x - ohlc[ohlc.length - 2].x;
var chart = Highcharts.stockChart('container', {
chart: {
borderWidth: 1,
panning: true,
},
title: {
text: 'Chart'
},
legend: {
enabled: true
},
rangeSelector: {
selected: 1,
enabled: false
},
scrollbar: {
enabled: false
},
xAxis: {
minPadding: 0.2,
overscroll: 50 * interval,
},
yAxis: [{
height: '40%'
}, {
top: '40%',
height: '30%',
offset: 0
}, {
top: '70%',
height: '30%',
offset: 0
}],
series: [{
type: 'candlestick',
id: 'candlestick',
name: 'AAPL',
data: ohlc,
tooltip: {
valueDecimals: 2
},
dataGrouping: {
enabled: false,
}
}, {
type: 'column',
id: 'volume',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
enabled: false,
}
}]
});
Here is live demo: http://jsfiddle.net/ogorobets/bfcs9gx7/2/
It's possible, however, it requires some custom logic. It can be achieved using xAxis.events.afterSetExtremes callback where you can check if the current axis minimum is greater than your limit (a value lower than maximum xData value). When it is true, set new axis extremes with your limit as a minimum value. Check the code and demo posted below.
Code:
xAxis: {
minPadding: 0.2,
overscroll: 50 * interval,
events: {
afterSetExtremes: function() {
var chart = this.chart,
xData = chart.series[0].xData,
maxValue = xData[xData.length - 5],
min = chart.xAxis[0].min,
max = chart.xAxis[0].max
if (min > maxValue) {
chart.xAxis[0].setExtremes(maxValue, max, true, false);
}
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/p6d73nk8/
API reference:
https://api.highcharts.com/highcharts/xAxis.events.afterSetExtremes
https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes

Echarts: Line dissapear when Zooming in

I try to programm a Line Chart in echarts Version 4.1.0. I'm using different browser like Chrome Version 69.0.3497.100 or Firefox 63.0.1 (64-Bit). My issue is, if I zoom the x axis, the connecting lines disappear if the points are outside the focus:
Thats my code for this example:
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.1.0-release/echarts-en.min.js"></script>
</head>
<body>
<div id="main_chart" style="width: 1200px;height:600px;"></div>
<script type="text/javascript">
// based on prepared DOM, initialize echarts instance
var myChart = echarts.init(document.getElementById('main_chart'));
var app = {};
option = null;
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
xAxis: {
type: 'time',
axisLabel: {
formatter: function (value) {
return echarts.format.formatTime('yyyy-MM-dd hh:mm:ss', value);
}
}
},
yAxis: {
type: 'value',
min: 'dataMin'
},
dataZoom: [
{
type: 'slider',
xAxisIndex: 0,
filterMode: 'filter'
},
{
type: 'slider',
yAxisIndex: 0,
filterMode: 'empty'
},
{
type: 'inside',
xAxisIndex: 0,
filterMode: 'filter'
},
{
type: 'inside',
yAxisIndex: 0,
filterMode: 'empty'
}
],
series: [{
data: [["2018-11-06 11:27:54",37.2],["2018-11-06 11:29:33",37.2],["2018-11-06 11:29:34",37.3],["2018-11-06 13:09:33",37.3],["2018-11-06 13:09:34",37.2],["2018-11-06 13:09:34",37.2],["2018-11-06 13:09:35",37.3],["2018-11-06 13:09:49",37.3],["2018-11-06 13:09:50",37]],
type: 'line',
// step: 'end',
// smooth: true,
sampling: 'average'
}]
};
;
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
</script>
</body>
</html>
When I zoom, the connecting lines should also connect points outside the display area. Below you could see the expected behaviour, which I did with a paint programm.
What could I change in the options to change that behavour, or is it an issue in the Echarts Library?
See the official documentation at https://echarts.apache.org/en/option.html#dataZoom-slider.filterMode for dataZoom: [{type: 'slider', ...}] and https://echarts.apache.org/en/option.html#dataZoom-inside.filterMode for dataZoom: [{type: 'inside', ...}].
The issue has to do with how ECharts filters the data when you zoom in. By default, it ignores all of the values outside of the axis range when you zoom in. Setting filterMode: 'none' will prevent the data from being ignored, and the lines will extend to the edge of the graph based on the values outside of the axis range.

Why does my addSeries (in highcharts) only display names of the series but not the actual pie chart itself

When trying to add Series to a Highcharts piechart only the names of the series displays but not the graph itself.
If I input the series manually the chart displays correctly but when it's done via .each loop it only shows the added series names.
Here is my code:
function my_pie(){
// Build the chart
$('#pie_chart').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
marginBottom: 0,
spacingTop: 0,
marginTop:0,
marginLeft:50,
marginRight:50
},
credits:{
enabled:false
},
title: {
text: ''
},
tooltip: {
pointFormat: '{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: false
}
},
series: [{
type: 'pie',
name: 'Innehav',
data: [ ]
}]
});
var chart = $('#pie_chart').highcharts();
$.each(data_array, function( index, value ) {
chart.addSeries({
name: index,
y: parseInt(value)
}, false);
});
chart.redraw();
};
Here is the output from console.log(data_array)
Object {Ja: "272", Nej: "30", Vet ej: "1"}
Update:
Here is how the data_array is generated (I added num_check to make values integers)
var data_array = <?php echo json_encode($data_pie, JSON_NUMERIC_CHECK ) ?>;
And now the console.log(data_array) looks like this:
Object {Ja: 272, Nej: 30, Vet ej: 1}
Pie chart is just one series, not multiple ones like other types. You should be adding values instead:
$.each(data_array, function( index, value ) {
chart.series[0].addPoint({
name: index,
y: parseInt(value)
}, false);
});
chart.redraw();
Or better, use setData:
var data = []
$.each(data_array, function( index, value ) {
data.push( [index, parseInt(value) ]);
});
chart.series[0].setData(data);

Categories