I'm trying to replicate the following code from a working example:
series: {0: {targetAxisIndex:0},
1: {targetAxisIndex:0},
2: {targetAxisIndex:1},
This is for setting which y-axis is used to plot different columns from a dataTable on a Google chart.
However I have a variable number of columns (based on user input), therefore am collecting an array of the required axis (the axisAssignment Array in the below example).
My code is below:
var series = {};
for (i=0;i<axisAssignment.length;i++)
{
series[i] = {targetAxisIndex: axisAssignment[i]};
}
return series;
However, all of my data is only being written to the left axis, despite the debugger suggesting that the object is correct. My option code is below:
var options =
{
hAxis: {title: xTitle},
vAxes: {0: {title: y1Type},
1: {title: y2Type}
},
series: calculateSeries(),
pointSize: 1,
legend: {position: 'top', textStyle: {fontSize: 10}}
};
Any assistance would be greatly apreciated.
Thanks
Tom
edit: whole file for reference (it's a work in progress so a bit of a mess I'm afraid)
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart());
function drawChart()
{
var title = "Node: "+currentNode;
var xTitle = "Date";
var yTitle = titles[currentVariable];
if (totalData !== null)
{
var tempData = newData();
var tempData2 = totalData;
dataArray[dataCount] = tempData;
var joinMark = countArray(dataCount);
totalData = google.visualization.data.join(tempData2,tempData,'full',[[0,0]],joinMark,[1]);
dataCount = dataCount+1;
}
else
{
totalData = newData();
dataArray[dataCount] = totalData;
dataCount = 1;
}
var options =
{
hAxis: {title: xTitle},
vAxes: {0: {title: y1Type},
1: {title: y2Type}
},
series: calculateSeries(),
pointSize: 0.5,
legend: {position: 'top', textStyle: {fontSize: 10}}
};
var chart = new google.visualization.ScatterChart(document.getElementById('graph'));
console.log(calculateSeries());
chart.draw(totalData, options);
function countArray(count)
{
var arrayCount= new Array();
if (count===1)
{
arrayCount[0] = count;
}
else
{
for (var i=0;i<count;i++)
{
var temp = i+1;
arrayCount[i] = temp;
}
}
return arrayCount;
}
function calculateSeries()
{
var series = {};
for (i=0;i<axisAssignment.length;i++)
{
series[i] = {targetAxisIndex: axisAssignment[i]};
}
return series;
}
function newData()
{
var dataType = dataIn[0];
dataIn.shift();
var axis = dataSelect(dataType);
axisAssignment.push(axis);
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', "Node: "+currentNode+": "+titles[currentVariable]);
var num = (dataIn.length);
data.addRows(num/2);
var i = 0;
var j = 0;
while (i<num)
{
var d = (dataIn[i]);
if (i%2===0)
{
d = new Date(d);
data.setCell(j,0,d);
i++;
}
else
{
data.setCell(j,1,parseFloat(d));
i++;
j++;
}
}
return data;
}
function dataSelect(type)
{
var axisNumber;
if (y1Type === null || y1Type === type)
{
y1Type = type;
axisNumber = 0;
}
else if (y2Type === null || y2Type === type)
{
y2Type = type;
axisNumber = 1;
}
else
{
alert("You already have 2 axes assigned.\n\nPlease clear the graph \nor select more objects of \ntype"+y1Type+" or \ntype "+y2Type+" to continue.");
axisNumber = null;
}
return axisNumber;
}
}
Ok, it seems that it's an issue with my choice of ScatterChart,
var options =
{
hAxis: {title: xTitle},
series: calculateSeries(),
vAxes: {0: {title: y1Type },
1: {title: y2Type}
},
pointSize: 0.5,
legend: {position: 'top', textStyle: {fontSize: 10}}
};
var chart = new google.visualization.LineChart(document.getElementById('graph'));
chart.draw(totalData, options);
I've changed it to LineChart and it's working fine, by keeping the pointSize option, the appearance is almost completely unchanged. Thanks for your help juvian.
Related
blue is the standard, the red is current mine
compared with these two diagrams, I do not no how to design the x-axis in the blue diagram, which is a range to describe the data.
Now, I using an array to store all value displayed, and on the y-axis, another array stores the times of each number displays. But I do not know make the X-axis to be a range.
<script>
var sheetName = null;
var sheets = null;
var ageArray = new Array();
var ageTimes = new Array();
function readExcel(file_obj){
var reader = new FileReader();
var file = file_obj.files[0];
reader.readAsBinaryString(file);
reader.onload = function (e) {
var data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
sheetName = wb.SheetNames[0] // 获取文档中第一个sheet页签的名字
sheets = wb.Sheets[sheetName] // 获sheet名页签下的数据
var json = XLSX.utils.sheet_to_json(sheets)
// console.log(sheets); // 返回sheet对象到控制台
// console.log(json.length);
// console.log(json);
for (let i = 0; i < json.length; i++) {
ageArray.push(json[i]['Age ']);
}
// console.log(ageArray);
function unique (arr) {
return Array.from(new Set(arr))
}
ageArray = unique(ageArray);
ageArray.sort(function (a,b){
if (a>b) {
return 1
} else if (a<b){
return -1
} else return 0
});
// console.log(ageArray);
// count times
let LevelList = json.map(item => {
return item['Age '];
})
let contlist = LevelList.reduce(function(prev,next){
prev[next] = (prev[next]+1) || 1;
return prev
},{});
console.log(contlist);
for (let j = 0; j < ageArray.length; j++) {
var index = ageArray[j];
// console.log(contlist[index]);//
ageTimes.push(contlist[index]);
// console.log(ageTimes);
}
var myChart = echarts.init(document.querySelector('.box'));
var option = {
title: {
text: 'ECharts'
},
tooltip: {},
legend: {
data: ['sale']
},
xAxis: {
data: ageArray,
},
yAxis: {
},
series: [
{
name: 'sale',
type: 'bar',
data: ageTimes
}
]
};
myChart.setOption(option);
};
}
</script>
<style>
.box {
width: 1000px;
height: 400px;
background-color: pink;
}
</style>
<body>
<input type="file" onchange="readExcel(this)" />
<div class="box"></div>
</body>
I have a chart to represent some temperatures of a specific place, I am using Google Chart tools (area chart), and Im trying to put a diferent color (orange) if the temperature is greater than 25 degrees
Javascript code
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Data');
data.addColumn('number', 'Temperatura ºC');
data.addColumn({ type: 'number', role: 'annotation' });
var array = JSON.parse('<%=jsonStringTemp%>');
console.log(array);
for(var i=0; i<array.length;i++){
var array2=[];
for (j = 0; j < array[i].length; j++){
if (typeof array[i][j]==='string') {
if (j !== 0) {
array[i][j]=parseInt(array[i][j], 10)
}
}
array2.push(array[i][j])
}
data.addRow(array2)
}
console.log(data)
var options = {
title: 'Temperatura',
hAxis: {title: 'Data', titleTextStyle: {color: '#333'}},
vAxis: { minValue: 0 },
series: {
0: {
color: 'green'
},
},
pointSize: 6
};
;
var chart = new google.visualization.AreaChart(document.getElementById('linechart_material'));
chart.draw(data, options);
}
output
Is it possible to do it? And How?
I have tweaked a few examples I found across the net that allow me to remove/greyout a series when it is clicked (legend or line itself).
I then wanted to add ability to switch between datatables and have what was hidden/greyedout to transfer to the new datatable.
I took the idea from switching data from https://developers.google.com/chart/interactive/docs/animation#value-changes
(my graphs are not animating correctly like the example)
My problem is I get very weird results when clicking on the "Switch" button and switching datatables, sometimes it will keep the correct selection but when you click on a different series one will magically appear or it will deselect a different series than the one clicked. I can't figure out to get it so both datatables maintain the same selection (selection meaning greyed out/removed series).
It's worth noting that
columns.push({
calc: 'stringify',
sourceColumn: i,
type: 'string',
role: 'annotation'
});
is adding hidden columns to aide in additional logic for the series. While I am not directly using it currently I want it to remain and work properly because I think I will use it in the future. These "hidden" columns add complexity where I think the bug lives.
The code is here:
var button = document.getElementById('b1');
var current = 0;
var data = [];
var chart;
var options;
var ms2 = [{
"LOCAL_ID": "W-133",
"Class1": 29,
"Class2": 3628,
"Class3": 159,
"Class4": 24,
"Class5": 65,
"Class6": 12,
"Class7": 0,
"Class8": 12,
"Class9": 110,
"Class10": 41,
"Class11": 0,
"Class12": 0,
"Class13": 0
}, {
"LOCAL_ID": "14-6A-060",
"Class1": 19,
"Class2": 290,
"Class3": 224,
"Class4": 0,
"Class5": 0,
"Class6": 0,
"Class7": 0,
"Class8": 2,
"Class9": 0,
"Class10": 0,
"Class11": 1,
"Class12": 0,
"Class13": 0
}, {
"LOCAL_ID": "45-5-006",
"Class1": 7,
"Class2": 191,
"Class3": 165,
"Class4": 0,
"Class5": 6,
"Class6": 3,
"Class7": 0,
"Class8": 4,
"Class9": 18,
"Class10": 11,
"Class11": 0,
"Class12": 0,
"Class13": 10
}];
google.charts.load('current', {
'packages': ['line']
});
google.charts.setOnLoadCallback(init);
button.onclick = function() {
current = 1 - current;
button.disabled = true;
options.chart['subtitle'] = (current ? 'View 1' : 'View 2');
chart.draw(data[current], options);
};
function getData() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Class');
ms2.forEach(function(masterLocation, index) {
data.addColumn('number', masterLocation.LOCAL_ID);
});
for (var i = 0; i < 13; i++) {
var arr = [i];
ms2.forEach(function(masterLocation, index) {
arr.push(masterLocation['Class' + i]);
});
data.addRow(arr);
}
return data;
}
function getRandomData(base) {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Class');
data.addColumn('number', ms2[0].LOCAL_ID);
data.addColumn('number', ms2[1].LOCAL_ID);
data.addColumn('number', ms2[2].LOCAL_ID);
// add random data
var y1 = base,
y2 = base,
y3 = base;
for (var i = 0; i < 13; i++) {
y1 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
y2 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
y3 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
data.addRow([i, y1, y2, y3]);
}
return data;
}
function init() {
data = [];
data[0] = getData();
data[1] = getRandomData(1000);
chart = new google.charts.Line(document.getElementById('chart_div'));
options = {
chart: {
title: 'Box Office Earnings in First Two Weeks of Opening',
subtitle: 'in millions of dollars (USD)'
},
width: 500,
height: 300,
vAxis: {
gridlines: {
color: '#ccc'
}
},
hAxis: {
gridlines: {
color: '#ccc'
}
},
animation: {
duration: 1000,
easing: 'out'
}
};
drawChart();
}
function drawChart() {
var columns = [];
var defaultSeries = [1, 2, 3];
var series = {};
for (var i = 0; i < data[current].getNumberOfColumns(); i++) {
if (i === 0 || defaultSeries.indexOf(i) > -1) {
// if the column is the domain column or in the default list, display the series
columns.push(i);
} else {
// otherwise, hide it
columns.push({
label: data.getColumnLabel(i),
type: data.getColumnType(i),
sourceColumn: i,
calc: function() {
return null;
}
});
}
if (i > 0) {
columns.push({
calc: 'stringify',
sourceColumn: i,
type: 'string',
role: 'annotation'
});
// set the default series option
series[i - 1] = {};
if (defaultSeries.indexOf(i) == -1) {
// backup the default color (if set)
if (typeof(series[i - 1].color) !== 'undefined') {
series[i - 1].backupColor = series[i - 1].color;
}
series[i - 1].color = '#CCCCCC';
}
}
}
options['series'] = series;
function showHideSeries() {
var sel = chart.getSelection();
if (sel.length < 1 || sel[0].row) {
return;
}
var col = sel[0].column;
if (typeof(columns[col]) == 'number') {
var src = columns[col];
var calcFunc = null;
if (document.getElementById("removeSeriesOnSelect").checked) {
calcFunc = function() {
return null;
};
}
columns[col] = {
label: data[current].getColumnLabel(src),
type: data[current].getColumnType(src),
sourceColumn: src,
calc: calcFunc
};
// grey out the legend entry
series[src - 1].color = '#CCCCCC';
} else {
var src = columns[col].sourceColumn;
// show the data series
columns[col] = src;
series[src - 1].color = null;
}
var view = new google.visualization.DataView(data[current]);
view.setColumns(columns);
chart.draw(view, options);
}
google.visualization.events.addListener(chart, 'select', showHideSeries);
google.visualization.events.addListener(chart, 'ready', function() {
button.disabled = false;
});
var view = new google.visualization.DataView(data[current]);
view.setColumns(columns);
chart.draw(view, options);
}
Here is the jsFiddle: https://jsfiddle.net/sp7atw1L/
Edit: I started a bounty. Given the global variables and maybe the indirect way this is doing things. I am not opposed to a direct refactor/redo that accomplishes the same thing.
Indeed the bug is related to annotation columns. After drawChart() your columns array is [0,1,{a},2,{a},3,{a}].
> when column 1 clicked, everything is ok.
> when column 2 clicked, columns[2] is {a}, which in your code is replaced by 1, so, you get another copy of column 1
> when column 3 clicked, columns[3] is 2, so, the wrong row is selected
These are consequences, but the problem lies in chart.getSelection() not taking into account annotation columns and returning wrong indexes. I am not sure why this happens, but if you draw DataView (instead of DataTable) in onclick handler like this
//chart.draw(data[current], options); <-------remove this
var view = new google.visualization.DataView(data[current]);
view.setColumns(columns);// <---make columns global
chart.draw(view, options);
it solves the issue. A related problem with annotations is e.g. here
Additionally, in getData() the line
arr.push(masterLocation['Class' + i]);
should be
arr.push(masterLocation['Class' + i+1]);
I used this ,to multiply doughnut chart according as array(arr) has,but it can't change to object,(data has string type).So chart doesn't appear here..,how fix it
var arr=['HTML','CSS','JS'],i,data;
data ='[';
for(i=0;i<arr.length;i++){
if(i==arr.length-1){
data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]}';
}
else{
data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]},';
}
}
data += ']';
var dat = data;
window.onload = function () {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myBar = new Chart(ctx).Doughnut(dat,{
responsive: true,
});
};
//want like this
dat =[{value:"300",color:"#fff",highlight:"#aaa",label:"HTML"},
{value:"200",color:"#fff",highlight:"#aaa",label:"CSS"}];
You are creating your array as a String.
You need to create an array of objects [{},{},{}].
The method used to INSERT a new object in an array is PUSH().
Check the fiddle. Now it´s working OK (move the mouse on the screen to see the chart is there (you will only see it when mouse is over it):
window.onload = function() {
var arr = ['HTML', 'CSS', 'JS'],
i, data;
data = [];
for (i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
data.push({
value: "300",
color: "#fff",
highlight: "#aaa",
label: arr[i]
});
} else {
data.push({
value: "300",
color: "#fff",
highlight: "#aaa",
label: arr[i]
});
}
}
var dat = data;
var ctx = document.getElementById("chart-area").getContext("2d");
window.myBar = new Chart(ctx).Doughnut(dat, {
responsive: true,
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/nnnick/Chart.js/master/Chart.js"></script>
<canvas id="chart-area"></canvas>
I am trying to display data using Google's Column chart. I tried displaying bars not stacked but it would not display one bar from both ends. Then i changed the property isStacked to true, it displays all the bars but it crops the bar at the both ends.
How can i fix this issue?
I was playing around with the options but nothing seems to work.
<script type='text/javascript'>
google.load('visualization', '1', { 'packages': ['corechart'] });
google.setOnLoadCallback(drawSizeChart);
var d = 0;
function drawSizeChart() {
$.post('/metrics/SiteResourceChart', { fnsId: "#Model.FnsId", regionId: selectedValue },
function (data) {
if (Object.keys(data).length !== 0) {
var tdata = new google.visualization.DataTable();
tdata.addColumn('date', 'Date');
for (var p = 0; p < data.length; ++p) {
tdata.addColumn('number', data[p][0].PathName);
}
d = data[0].length;
for (var i = 0; i < data.length; ++i) {
for (var j = 0; j < data[i].length; ++j) {
var date = new Date(parseInt(data[i][j].CreatedAt.substr(6)));
var rCount = data[i][j].ResourceCount;
if (i === 0)
tdata.addRow([date, rCount, null]);
else
tdata.addRow([date, null, rCount]);
}
}
var options = {
title: 'Resource Count',
titleTextStyle: { fontSize: 20 },
isStacked: true,
bar: { groupWidth: '20%' },
chartArea: { left: '50' },
hAxis: { viewWindowMode: 'maximized' }
//legend: { position: 'none' }
};
var chart = new google.visualization.ColumnChart(document.getElementById('site_size_chart'));
chart.draw(tdata, options);
}
}
);
}
</script>
I guess a quick solution would be to define your first column as 'string' instead of Date and leave the hAxis.viewWindowMode as default. Otherwise, you should configure hAxis.viewWindow object (i.e., min/max values).
Same issue here. What I did is that I added dummy data with a 0 value one day before the first date and one day after the last date in order to achieve the desired result.
Using the columnchart package wasn't a solution for me because I had days without data but wanted to keep the time axis proportional.