Programmatically Pivoting the Google Visualization dataTable - javascript

I excited with this fiddle and I tried to create the same kind with reference to that fiddle. My modified sample is given in here and i'm trying to create a view as follows.
var distinctValues = data.getDistinctValues(2);
var viewColumns = [1];
var groupColumns = [];
// build column arrays for the view and grouping
for (var i = 0; i < distinctValues.length; i++) {
viewColumns.push({
type: 'number',
label: distinctValues[i],
aggregation: google.visualization.data.count
});
groupColumns.push({
column: i+1,
type: 'number',
//label: distinctValues[i],
aggregation: google.visualization.data.sum
});
}
But my aim is to create a pivot table something like as follows.
['Column1', 'Column2', 100, 200, 300, 400],
['A', 'bar', 0, 1, 1, 0],
['A', 'baz', 0, 0, 1, 0],
['A', 'foo', 3, 1, 0, 0],
['B', 'baz', 0, 1, 0, 0],
['B', 'cad', 1, 0, 1, 1],
['B', 'qud', 1, 1, 1, 2]
How can I proceed?

You have to change a few things in your code. First, the viewColumns needs to contain both columns 0 and 1 to start if you want Column1 and Column2 to both be in the output. Then, you need to adjust the columns you add to the viewColumns: each one needs a calc parameter which calculates the value in the column. In this case, you want to compare the value of the column to distinctValues[i] and return 1 when they match and 0 when they don't. In the aggregation function for groupColumns, use sum instead of count:
var distinctValues = data.getDistinctValues(2);
var viewColumns = [0, 1];
var groupColumns = [];
// build column arrays for the view and grouping
for (var i = 0; i < distinctValues.length; i++) {
viewColumns.push({
type: 'number',
label: distinctValues[i],
calc: (function (x) {
return function (dt, row) {
return (dt.getValue(row, 2) == x) ? 1 : 0;
}
})(distinctValues[i])
});
groupColumns.push({
column: i+2,
type: 'number',
//label: distinctValues[i],
aggregation: google.visualization.data.sum
});
}
Then, in the grouping function, pass columns 0 and 1 in the first array:
var pivotedData = google.visualization.data.group(view, [0, 1], groupColumns);
See these changes working here: http://jsfiddle.net/asgallant/DUn6B/1/

Related

Highcharts: series does not update if previous array only had null values

I have an Highchart which updates the series. In some cases (like the fiddle shows), the update does not work correctly.
When the series had an array which only had null-values, the next given array does not take effect.
https://jsfiddle.net/ChrisCross82/ubz3o4pr/
<body>
<button onclick="firstData()">1st Data</button>
<button onclick="secondData()">2nd Data</button>
<button onclick="firstData()">Again 1st Data (without Series1)</button>
<div id="chart1" style="height: 300px"></div>
</body>
var chart1;
chart1 = Highcharts.chart('chart1', {
series: [{
data: [],
},{
data: [],
}]
});
function firstData() {
var series1 = [65.4, 72.7, 70, 60.6, 42.9];
var series2 = [26, 33, 10, 33, 7];
updateChart(series1, series2);
}
function secondData() {
var series1 = [null, null, null, null, null];
var series2 = [0, 0, 0, 0, 0];
updateChart(series1, series2);
}
function updateChart(series1, series2){
chart1.update({
series: [{
data: series1
},{
data: series2,
}]
});
}
For now, I check the array, and if every value in the array is null, I set the array to []. After this, the update works. But I think this is not the best solution.
This problem looks like a bug, so I reported it on Highcharts github: https://github.com/highcharts/highcharts/issues/9290
It is worth noting that only update with the same number of data causes the issue: https://jsfiddle.net/BlackLabel/8nbdy9wq/
To workaround, you can update the chart with null values as y property:
function secondData() {
var series1 = [{
y: null
}, {
y: null
}, {
y: null
}, {
y: null
}, {
y: null
}];
var series2 = [0, 0, 0, 0, 0];
updateChart(series1, series2);
}
Live demo: https://jsfiddle.net/BlackLabel/cnw4vh65/

DynamicSlope not working in d3 funnel chart

I trying to d3 funnel chart with 0 values its not working properly.I enabled dynamicSlope option is true funnel chart not working.
See my example:
http://jsfiddle.net/3x265bLj/7/
I added six values l0,l1,l2....L6 and l3 value is 0.Once i enabled dynamicSlope option is true Funnel chart only showing L0,L1,L2 value only but need L3,L4,L5.
const data = [
['l0', 13],
['l1', 7],
['l2', 12],
['l3', 0],
['l4', 8],
['l5', 3]
];
const options = {
chart: {
width: 200,
height: 450,
bottomWidth: 1 / 2,
bottomPinch: 1,
inverted: false,
horizontal: false,
animate: 0,
curve: {
enabled: true,
height: 20,
shade: -0.4
}
},
block: {
dynamicSlope: true,
dynamicHeight: true,
highlight: true
}
};
const chart = new D3Funnel('#funnel');
chart.draw(data, options);
Console Issues:
Error: <path> attribute d: Expected number, "MNaN,562.5 LNaN,5…".
The
Error: <path> attribute d: Expected number, "MNaN,562.5 LNaN,5…".
Means The function try to convert data to height format, but you input 0 that means 0 height, the function reject you.
what is the purpose of drawing 0 data? axample, if the function can do
it, the data will not showing on the chart, because it has 0 height,
am i correct?
thare is 2 solution for your problem, first you change the data value to 0.01 before draw it
var data = [
['l0', 13],
['l1', 7],
['l2', 12],
['l3', 0],
['l4', 8],
['l5', 3]
];
var newdata = data.map(function (d,i){
var new_d = d
if (new_d[1] == 0){
new_d[1] = 0.01
}
return new_d
})
chart.draw(newdata, options);
second, you add the filter function before draw it
var data = [
['l0', 13],
['l1', 7],
['l2', 12],
['l3', 0],
['l4', 8],
['l5', 3]
];
var newdata = data.filter(function (d,i){
return d[1] !== 0
})
chart.draw(newdata, options);

Google Column Chart with two columns

How to approach a column chart when having month and year.
My data is in this format
['Group','Count','Month','Year'],
['A',10,'February',2015],
['B',8,'February',2015],
['C',15,'February',2016]
Aim is to create a column chart which has X-axis as Month and Y-axis as Count. Now X-axis should have Count for years grouped by month.
Something like this -
I tried to simply pass the above data to see what I can get, but I get error.
Any way to assign Axis the values based on year grouped by month ?
JsFiddle of Google Chart Example
just need three columns, something like this...
['Month', '2015', '2016'],
['Jan', 10, 15],
['Feb', 12, 18],
['Mar', 14, 21],
['Apr', 16, 24]
then you can use a DataView to add the annotations, via calculated columns...
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}]);
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Month', '2015', '2016'],
['Jan', 10, 15],
['Feb', 12, 18],
['Mar', 14, 21],
['Apr', 16, 24]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}]);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(view, {});
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
all google charts require a specific DataFormat
meaning, manipulation is required if your data does not already exist in this format
the visualization library does offer some Data Manipulation Methods, such as group()
which could be used to transform the data into the required format
1) group the data by Month and Year
2) create a new DataTable with the Month column
3) add a column for each Year from the grouped table
4) add the rows for each month
see following working snippet, using the data from the question...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Group', 'Count', 'Month', 'Year'],
['A', 10, 'February', 2015],
['B', 8, 'February', 2015],
['C' , 15, 'February', 2016]
]);
// group by month / year
var dataGroup = google.visualization.data.group(
data,
[2, 3],
[{column: 1, aggregation: google.visualization.data.sum, type: 'number', label: 'Count'}]
);
dataGroup.sort([{column: 0},{column: 1}]);
// build final data table
var yearData = new google.visualization.DataTable({
cols: [
{label: 'Month', type: 'string'}
]
});
// add column for each year
var years = dataGroup.getDistinctValues(1);
for (var i = 0; i < years.length; i++) {
yearData.addColumn(
{label: years[i], type: 'number'}
);
}
// add row for each month
var rowMonth = null;
var rowIndex = null;
for (var i = 0; i < dataGroup.getNumberOfRows(); i++) {
if (rowMonth !== dataGroup.getValue(i, 0)) {
rowMonth = dataGroup.getValue(i, 0);
rowIndex = yearData.addRow();
yearData.setValue(rowIndex, 0, rowMonth);
}
for (var x = 1; x < yearData.getNumberOfColumns(); x++) {
if (yearData.getColumnLabel(x) === dataGroup.getValue(i, 1).toString()) {
yearData.setValue(rowIndex, x, dataGroup.getValue(i, 2));
}
}
}
var view = new google.visualization.DataView(yearData);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}, 2, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
chart.draw(view);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

How to retain tooltip when pivoting Google Visualization DataTable

I'm using some great code from #asgallant to pivot a Google DataTable for use in a line chart. His code is here: http://jsfiddle.net/asgallant/HkjDe/
In my original DataTable I have a 4th column however that is a tooltip string. When I pivot the table with his code my tooltip if no longer available. I would like to use the tooltips provided and for the cells that are 'created' use some standard tooltip text. Here is what my version of the initial table setup looks like.
var data = new google.visualization.DataTable();
data.addColumn('number', 'A');
data.addColumn('string', 'B');
data.addColumn('number', 'C');
data.addColumn({type: 'string', role: 'tooltip'});
data.addRows([
[1, 'foo', 6, 't1'],
[2, 'foo', 2, 'hello'],
[3, 'foo', 1, 't2'],
[4, 'foo', 3, 'test'],
[1, 'bar', 7, 't3'],
[2, 'bar', 3, 'again'],
[1, 'baz', 8, 't4'],
[2, 'baz', 4, 'and'],
[2, 'cad', 5, 't5'],
[3, 'cad', 6, 'again'],
[1, 'qud', 9, 'x'],
[5, 'qud', 1, 'z']
]);
Can anyone provide some assistance?
-- UPDATE --
Edited the initial addRows statement to be more representative of my data model.
In order to preserve the tooltips, you need to add tooltip columns to the view and pivot data:
for (var i = 0; i < distinctValues.length; i++) {
viewColumns.push({
type: 'number',
label: distinctValues[i],
calc: (function (x) {
return function (dt, row) {
// return values of C only for the rows where B = distinctValues[i] (passed into the closure via x)
return (dt.getValue(row, 1) == x) ? dt.getValue(row, 2) : null;
}
})(distinctValues[i])
});
groupColumns.push({
column: (i * 2) + 1,
type: 'number',
label: distinctValues[i],
aggregation: google.visualization.data.sum
});
// add columns for the tooltips
viewColumns.push({
type: 'string',
calc: (function (x) {
return function (dt, row) {
// return values of the tooltip column only for the rows where B = distinctValues[i] (passed into the closure via x)
return (dt.getValue(row, 1) == x) ? dt.getValue(row, 3) : null;
}
})(distinctValues[i])
});
groupColumns.push({
column: (i * 2) + 2,
type: 'string',
aggregation: function (values) {
return values.join('');
}
});
}
The group function does not handle column roles properly, so you have to set them afterwards:
// fix the tooltip column roles, since the group function won't create them properly
for (var i = 1; i < pivotedData.getNumberOfColumns(); i++) {
if (pivotedData.getColumnType(i) == 'string') {
pivotedData.setColumnProperty(i, 'role', 'tooltip');
}
}
See example: http://jsfiddle.net/asgallant/HkjDe/23/

Google charts API scatter chart with legend and other colors

I have this one example:
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart1);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart1() {
var data = new google.visualization.DataTable(
{
cols: [
{id: 'A', label: 'A', type: 'number'},
{id: 'B', label: 'B', type: 'number'},
{id: 'C', label: 'C', type:'tooltip', p:{role:'tooltip'}}
],
rows: [
{c:[{v: 2}, {v: 3}, {v:'Allen'}]},
{c:[{v: 4}, {v: 2}, {v:'Tom'}]},
{c:[{v: 1}, {v: 3}, {v:'Sim'}]}
]
})
var options = {
title: 'Age vs. Weight comparison',
hAxis: {title: 'Age', minValue: 1, maxValue: 5},
vAxis: {title: 'Weight', minValue: 1, maxValue: 5},
legend: ''
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart_scatter_container'));
chart.draw(data, options);
}
http://jsfiddle.net/eAWcC/1/
when i hover once data, tooltip will see me label for this data. That is good.
But I want to see all the values ​​are different color and placed in the legend.
How to do it?
The columns in the datatable of a scatterchart are the ones that are shown in the legend, and are colored differently. In order to display them separately you need to rearrange your data so that each person has their own column.
For instance, replace your data table variable with this:
var data = google.visualization.arrayToDataTable([
['x', 'Allen', 'Tom', 'Sim'],
[1, null, null, 3],
[2, 3, null, null],
[4, null, 2, null],
]);
Doing this will give you the desired output (I believe, check here).
However, the issue with this method is that you end up with a lot of 'null' values in each series (since you just have single points). In order to simplify this process, you could write a loop to go through your data and format it appropriately for the new table. The basic code would be:
Add a column for your X values to a new table
For each row in column 2 (tooltips) create a new column in the new table
For each row in column 1 (Y values) fill diagonally down/right
This would look something like this:
var newTable = new google.visualization.DataTable();
newTable.addColumn('number', 'Age');
for (var i = 0; i < data.getNumberOfRows(); ++i) {
newTable.addColumn('string', data.getValue(i, 2));
newTable.addRow();
}
for (var j = 0; j < data.getNumberOfRows(); ++j) {
newTable.setValue(j, j + 1, data.getValue(j, j + 1));
}
(Above code has been tested but doesn't like the second for() loop for reasons beyond my comprehension).

Categories

Resources