Two chart forming instead of one chart - javascript

I am making a doughnut chart using canvas js. I am using a custom js code where I am taking a response from XML and then pointing the data points
Here when I am changing the type of chart to "line" the graph is behaving as it should but when I am changing the chart type to “pie” or “doughnut” so now instead of one chart it is giving me two charts. How it working could someone please through a light?
My code is
$scope.loadChartValue = function (data, scopes) {
scopes.data_id = [];
scopes.legend_text = "";
scopes.inner_chart_data = [];
for (var i = 0; i <= data.length; i++) {
var arrayvalue = data[0].data[i]._attr;
if (existsInArray(scopes.data_id, arrayvalue.label._value) == false) {
scopes.data_id.push(arrayvalue.label._value);
}
}
for (var i = 0; i < scopes.data_id.length; i++) {
scopes.inner_chart_data = [];
for (var j = 0; j <= data.length; j++) {
if (data[0].data[j]._attr.label._value == scopes.data_id[i]) {
scopes.inner_chart_data.push({ label: data[0].data[j]._attr.label._value, y: data[0].data[j]._attr.value._value });
scopes.legend_text = data[0].data[j]._attr.label._value;
}
}
scopes.dataset.push(
{
type: "doughnut",
markerType: "circle",
markerSize: scopes.markersize,
color: scopes.chart_color_value[i],
showInLegend: true,
name: scopes.legend_text,
legendText: scopes.legend_text,
dataPoints: scopes.inner_chart_data
}
);
}
scopes.data_length = data.length / scopes.data_id.length;
}

Line, Column and other chart-types supports multi-series whereas pie/doughnut is single series charts.
You are creating multiple data-series instead of 1 data-series with multiple dataPoints. Creating single series with multiple dataPoints instead of multiple dataSeries will work fine.

Related

Google charts - histogram: extra bars appearing alongside data

I'm using Google's histogram functionality in JavaScript to graph the output of a stochastic model, and it's overlaying extra bars on top of an otherwise nice chart.
The chart is generated by running the calculate_display_coverage() function hundreds of times with different inputs. I assure you the inner workings of the function aren't a problem here (I can't really post my whole Fiddle, but I show what the data look like in my code snippet).
gender = {
gender1: "Male",
gender2: "Female"
};
device = {
device1: "Tablet",
device2: "Mobile",
device3: "Desktop"
};
var paramstring = "";
resultArray = [];
resultArray[0] = ['Run','Coverage'];
var q = 1;
for (var x = 0; x < 100; x++) {
for (var y in gender) {
for (var w in device) {
for (var z = 1950; z < 1980; z++) {
paramstring = "09/21/";
paramstring += z.toString();
resultArray[q] = [q,calculate_display_coverage('SIW', y, paramstring, w).displayed];
q++
}
}
}
}
// dataset looks like [['Run','Coverage'],[1,80000],[2,42000],...]
google.charts.load("current", {packages:["corechart"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable(resultArray);
var options = {
title: 'Model output by coverage',
legend: { position: 'none' },
};
var chart = new google.visualization.Histogram(document.getElementById('chart_div'));
chart.draw(data, options);
}
With HTML:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js">
</script>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
In this case, where x = 100, the histogram includes these extra bars
Somewhat different formatting but same issue for more runs, where x = 2000.
Anyone seen this before?
The problem is that both columns of your data are numeric. Currently it has the format
[['Run','Count'],[1,80000],[2,42000],...]
So the histogram is including the index values as datapoints. You need to cast them as strings, so in the above code, the statement should be
resultArray[q] = [q.toString(),calculate_display_coverage('SIW', y, paramstring, w).displayed];
// [['Run','Count'],['1',80000],['2',42000],...]
That will remove the extra bars.

Using Morris.js line chart, do not show point for empty value

I'm using Morris.js to create a line graph.
Data is returned to me like this:
[{XValue:1,YValue1:1007,Yvalue2:1014},
{XValue:2,YValue1:1023,Yvalue2:1029},
{XValue:3,YValue1:0,Yvalue2:1041},
{XValue:4,YValue1:0,Yvalue2:1056},...];
I don't want to display 0 values, so I am replacing the zeroes with '' in my json prior to giving it morris to render:
for (var i = 0; i < json.length; i++) {
if (json[i].YValue1 == 0) {
json[i].YValue1 = '';
}
}
Morris.Line({
element: 'TotalLoad',
data: json,
xkey: 'XValue',
ykeys: ['YValue1','YValue2'],
ymin: 1000,
ymax: 3000,
parseTime: false,
labels: ['Actual', 'Forecast'],
events: [hour - 1],
eventStrokeWidth: 2,
continuousLine: false
});
My output looks like this:Morris Chart
The Y Values with no value show no line(which is the intended effect) but the point still appears at the top of the graph, although it is half cut off. The label shows 'NaN', which is fine with me if I can get the point to disappear!
Try changing this
for (var i = 0; i < json.length; i++) {
...
json[i].YValue1 = '';
...
}
to replace with null instead:
for (var i = 0; i < json.length; i++) {
...
json[i].YValue1 = null;
...
}

JQPlot not using the correct dates

I'm drawing a graph using jqplot but it's plotting against the wrong date. see the code snippet and image below.
else if(rtype === "DATE AXES"){
$scope.pl = [[]];
for (var i = 0; i < plotVal.length; i++) {
console.log(plotVal[i].x+", "+plotVal[i].y);
$scope.pl.push([new Date(plotVal[i].x), plotVal[i].y]);
}
var data = $scope.pl;
console.log("data: ");
console.log(data)
jQuery.jqplot("chartdiv", [data],
{
axes:{
xaxis:{
renderer:$.jqplot.DateAxisRenderer,
}
},
series:[{color:'#5FAB78', markerOptions:{style:'square'}}],
});
}
Any idea what's wrong?
Found the problem. It's the pl array in the code; passed an empty value into it first, so it distorted the arrangement
$scope.pl = [[]];
was suppoed to be:
$scope.pl = [];

C3.js "Uncaught Error: Source data is missing a component at (1,844)!"

I am using C3.js and Electron (Atom Shell) to make a desktop application for data visualization. I am having trouble to feed my data into C3. I have a DataArray that contains all the coordinates: DataAray = [ [x1,y1] , [x2,y2] , [x3,y3],...].
I use the following code to break it into an xData array and a yData array:
xData = [];
yData=[];
xData.push('data1_x');
yData.push('data1');
for (var i = 0; i < DataArray.length ; i++){
xData.push (DataArray[i][0]);
yData.push (DataArray[i][1]);
}
var chart = c3.generate({
bindto: '#chart',
data: {
xs: {
data1: 'data1_x',
},
columns: [
x,
y
],
type: 'scatter'
}
});
but when I run the application, I get this error:
"Uncaught Error: Source data is missing a component at (1,844)!", source: PATH/To/c3-0.4.10/c3.min.js (2)
and the graph is not plotted at all. If I change the for loop to
for (var i = 0; i < 843 ; i++)
however, it does plot the graph.
I was using Plotly before, and I used to run the exact same code to prepare the data for Plotly, and it worked just fine. What is the problem here? Also, is there a way to ask C3 to ignore errors in the data? For example, if there is a null at one of the points, is there a way for C3 to plot the graph anyways?
I don't know if there is a way to configure C3 to ignore null or undefined values. Try ignoring the null/undefined values so that C3 can plot the graph.
for (var i = 0; i < DataArray.length ; i++) {
// if the value is not undefined or null, push to array
if (DataArray[i][0] !== undefined && DataArray[i][0] !== null) {
xData.push (DataArray[i][0]);
} else {
// push 0 to signify no data
xData.push(0);
}
...
}
C3 will ignore null values. But you will get this error when a value is undefined. The answer from TonalLynx will work. Or you could change undefined values to null.
for (var i = 0; i < DataArray.length ; i++) {
// if the value is undefined, push null to array
if (DataArray[i][0] === undefined) {
xData.push (null);
} else {
xData.push (DataArray[i][0]);
}
...
}
c3 has an internal function that can help do that
c3_chart_internal_fn.convertColumnsToData = function (columns) {
var new_rows = [], i, j, key;
for (i = 0; i < columns.length; i++) {
key = columns[i][0];
for (j = 1; j < columns[i].length; j++) {
if (isUndefined(new_rows[j - 1])) {
new_rows[j - 1] = {};
}
if (isUndefined(columns[i][j])) {
throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
}
new_rows[j - 1][key] = columns[i][j];
}
}
return new_rows;
};

Polyline not showing, it does show when chopped in smaller lines

I'm trying to show a line but when I initiate the polyline like this nothing shows:
var geopositions = [];
for (var i = 0; i < c.geo.length; i++) {
var g = c.geo[i];
geopositions.push(parseFloat(g.lon));
geopositions.push(parseFloat(g.lat));
}
var line = {
positions: Cesium.Cartesian3.fromDegreesArray(geopositions),
width: 1,
id: "C" + c.id,
material: Cesium.Material.fromType('Color', {
color: Cesium.Color.fromBytes(255, 0, 0, 255)
}),
show: true
}
var coll = new Cesium.PolylineCollection();
coll.add(line);
primitives.add(coll);
So I thought I'd try to draw lines between all the points of the line (the points in c.geo) like so:
var collection = new Cesium.PolylineCollection();
var prev = null;
for (var j = 0; j < c.geo.length; j++) {
var geo = c.geo[j];
if (prev) {
collection.add(
{
positions: Cesium.Cartesian3.fromDegreesArray([
parseFloat(prev.lon), parseFloat(prev.lat),
parseFloat(geo.lon), parseFloat(geo.lat)]),
width: 2,
material: Cesium.Material.fromType('Color', {
color: Cesium.Color.fromBytes(0, 180, 0, 255)
})
}
);
}
prev = geo;
}
primitives.add(collection);
For some reason this does show the line. I can't find the reason why this would be the case and don't understand why a list of lines does show and a standard polyline doesn't show. Does anyone know how to show the line without chopping the line up in small polylines?
Cesium is supposed to handle the case you described. You are most likely running into some form of this bug; which has been fixed with this pull request.
I fixed the problem.
Apparently the Cesium.Polyline doesn't appreciate two consecutive coordinates (both lat and lon) that are exactly the same. The problem seems to be solved by removing the extra coordinates.

Categories