I am trying to implement a drill in or drill down in a pie chart. I actually have a working drill down pie chart, however, when I changed the values of the collection, it did not work. I am wondering what went wrong as I completely followed the working code and just replaced its values. The chart simply does not show up and has an error: Uncaught Error: Unknown header type: 17format+en,default+en,ui+en,controls+en,corechart+en.I.js:191. I am not sure though whether this error is related to the problem.
Javascript:
google.load('visualization', '1', {packages: ['corechart', 'controls']});
google.setOnLoadCallback(drawChart1);
var index = 0;
function drawChart1() {
<%
int aku = 0, cdu = 0, ls = 0, ptr = 0, rad = 0, oper = 0;
int aku1 = 0, aku2 = 0, aku3 = 0, aku4 = 0, aku5 = 0;
int cdu1 = 0, cdu2 = 0, cdu3 = 0, cdu4 = 0, cdu5 = 0, cdu6 = 0;
int ls1 = 0, ls2 = 0, ls3 = 0, ls4 = 0, ls5 = 0, ls6 = 0, ls7 = 0, ls8 = 0, ls9 = 0, ls10 = 0;
int ptr1 = 0, ptr2 = 0, ptr3 = 0, ptr4 = 0;
int rad1 = 0, rad2 = 0, rad3 = 0;
int oper1 = 0;
%> //Dummy values
//Main
var main = [
['Artificial Kidney Unit', <%=aku%>],
['Cardiac Diagnostic Unit', <%=cdu%>],
['Laboratory Services', <%=ls%>],
['Physical Therapy and Rehabilitation', <%=ptr%>],
['Radiology', <%=rad%>],
['Operations', <%=oper%>]
];
//Aku
var akuu = [
['Hemodialysis', <%=aku1%>],
['Peritoneal Dialysis', <%=aku2%>],
['Continuous Renal Replacement Therapy', <%=aku3%>],
['Sustained Low Efficient Dialysis', <%=aku4%>],
['Private Dialysis Suite', <%=aku5%>]
];
//Cdu
var cduu = [
['Electrocardiography', <%=cdu1%>],
['Ambulatory Electrocardiography', <%=cdu2%>],
['Exercise Stress Test', <%=cdu3%>],
['2D Echo', <%=cdu4%>],
['Lower Extremity Arterial & Venous Color Duplex Scan', <%=cdu5%>],
['Carotid Artery Duplex Scan', <%=cdu6%>]
];
//Ls
var lss = [
['Hematology', <%=ls1%>],
['Blood Chemistry', <%=ls2%>],
['Immunology and Serology', <%=ls3%>],
['Clinical Microscopy', <%=ls4%>],
['Microbiology', <%=ls5%>],
['Blood Bank and Transfusion Services', <%=ls6%>],
['Drug Testing', <%=ls7%>],
['Parasitology', <%=ls8%>],
['Surgical Pathology', <%=ls9%>],
['Cytopathology', <%=ls10%>]
];
//Ptr
var ptrr = [
['Physical Therapy', <%=ptr1%>],
['Occupational Therapy', <%=ptr2%>],
['Ultrasound Diagnostic Therapy', <%=ptr3%>],
['Orthotics and Prosthetic Evaluation', <%=ptr4%>]
];
//rad
var radd = [
['X-ray', <%=rad1%>],
['Ultrasound', <%=rad2%>],
['CT Scan', <%=rad3%>]
];
//oper
var operr = [
['Surgery', <%=oper1%>]
];
var collection = [];
collection[0] = google.visualization.arrayToDataTable(main);
collection[1] = google.visualization.arrayToDataTable(akuu);
collection[2] = google.visualization.arrayToDataTable(cduu);
collection[3] = google.visualization.arrayToDataTable(lss);
collection[4] = google.visualization.arrayToDataTable(ptrr);
collection[5] = google.visualization.arrayToDataTable(radd);
collection[6] = google.visualization.arrayToDataTable(operr);
var options1 = {
title: 'Departments',
animation: {'duration': 500,
'easing': 'in'},
action: function() {
button.onclick = function() {
recreateDashboard(0);
};
}
};
var chart1 = new google.visualization.PieChart(document.getElementById('chart1'));
google.visualization.events.addListener(chart1, 'select', drillIn);
google.visualization.events.addListener(chart1, 'click', drillOut);
chart1.draw(collection[0], options1);
function drillIn() {
var sel = chart1.getSelection();
var row = chart1.getSelection()[0].row;
options1['title'] = collection[index].getValue(sel[0].row, 0);
if(index === 0) {
if(row === 0) {
index = 1;
}
if(row === 1) {
index = 2;
}
if(row === 2) {
index = 3;
}
if(row === 3) {
index = 4;
}
if(row === 4) {
index = 5;
}
if(row === 5) {
index = 6;
}
}
else if(index === 1 || index === 2 || index === 3 || index === 4 || index === 5 || index === 6) {
options1['title'] = '# of services rendered in <%=year%>';
index = 0;
}
chart1.draw(collection[index], options1);
}
function drillOut(e) {
if(e.targetID === "title") {
if(index !== 0)
index--;
else if(index === 4 || index === 6 || index === 8)
index -= 2;
chart1.draw(collection[index], options1);
}
}
Html:
<div id="chart1">
</div>
I have figured out the mistake. All of these need a title before inputting the values.
Revised code:
//Main
var main = [
['Department', 'Value'],
['Cardiac Diagnostic Unit', <%=cdu%>],
['Laboratory Services', <%=ls%>],
['Physical Therapy and Rehabilitation', <%=ptr%>],
['Radiology', <%=rad%>],
['Operations', <%=oper%>]
];
//Aku
var akuu = [
['Service', 'Value'],
['Hemodialysis', <%=aku1%>],
['Peritoneal Dialysis', <%=aku2%>],
['Continuous Renal Replacement Therapy', <%=aku3%>],
['Sustained Low Efficient Dialysis', <%=aku4%>],
['Private Dialysis Suite', <%=aku5%>]
];
//Cdu
var cduu = [
['Service', 'Value'],
['Electrocardiography', <%=cdu1%>],
['Ambulatory Electrocardiography', <%=cdu2%>],
['Exercise Stress Test', <%=cdu3%>],
['2D Echo', <%=cdu4%>],
['Lower Extremity Arterial & Venous Color Duplex Scan', <%=cdu5%>],
['Carotid Artery Duplex Scan', <%=cdu6%>]
];
//Ls
var lss = [
['Service', 'Value'],
['Hematology', <%=ls1%>],
['Blood Chemistry', <%=ls2%>],
['Immunology and Serology', <%=ls3%>],
['Clinical Microscopy', <%=ls4%>],
['Microbiology', <%=ls5%>],
['Blood Bank and Transfusion Services', <%=ls6%>],
['Drug Testing', <%=ls7%>],
['Parasitology', <%=ls8%>],
['Surgical Pathology', <%=ls9%>],
['Cytopathology', <%=ls10%>]
];
//Ptr
var ptrr = [
['Service', 'Value'],
['Physical Therapy', <%=ptr1%>],
['Occupational Therapy', <%=ptr2%>],
['Ultrasound Diagnostic Therapy', <%=ptr3%>],
['Orthotics and Prosthetic Evaluation', <%=ptr4%>]
];
//rad
var radd = [
['Service', 'Value'],
['X-ray', <%=rad1%>],
['Ultrasound', <%=rad2%>],
['CT Scan', <%=rad3%>]
];
//oper
var operr = [
['Service', 'Value'],
['Surgery', <%=oper1%>]
];
Related
I am loading data from the file that contain the time stamp and temperature reading.
Difference between two data can be same or some time it can be a month or so.
Can we update the x axis scale so it min and max value matches the data received.
call back function of the zoom plug in is
let timer;
function update_chart({ chart }) {
clearTimeout(timer);
timer = setTimeout(() => {
var { min, max } = chart.scales.x;
// console.log(min);
// console.log(max);
console.log("Min Location: ", chart.scales.x2.min);
console.log("Max Location: ", chart.scales.x2.max);
var file_min = chart.scales.x2.min;
var file_max = chart.scales.x2.max;
file_min = makeCorrection(file_min);
file_max = makeCorrection(file_max);
console.log("Zoom level", chart.getZoomLevel());
var total_sample = (file_max - file_min) / 116;
console.log("Totoal samples: ", total_sample);
var offset = (total_sample / 50) * 116;
offset = makeCorrection(offset);
console.log("Offfset: ", offset);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var x = [], y1 = [], y2 = [], y3 = [], y4 = [], y5 = [], y6 = [], y7 = [], y8 = [], y9 = [], y10 = [];
var tex = this.responseText;
if (tex[0] == ">") {
window.alert(tex);
}
else {
dataray = tex.split('\n');
//console.log(dataray);
dataray.forEach(element => {
dat = element.split(';');
if (dat.length > 5) {
x.push(dat[0]);
y1.push(dat[1]);
y2.push(dat[2]);
y3.push(dat[3]);
y4.push(dat[4]);
y5.push(dat[5]);
y6.push(dat[6]);
y7.push(dat[7]);
y8.push(dat[8]);
y9.push(dat[9]);
y10.push(dat[10]);
}
});
if (x.length > 10)
{
myLineChart.data.labels = x;
myLineChart.data.datasets[0].data = y1;
myLineChart.data.datasets[1].data = y2;
myLineChart.data.datasets[2].data = y3;
myLineChart.data.datasets[3].data = y4;
myLineChart.data.datasets[4].data = y5;
myLineChart.data.datasets[5].data = y6;
myLineChart.data.datasets[6].data = y7;
myLineChart.data.datasets[7].data = y8;
myLineChart.data.datasets[8].data = y9;
myLineChart.data.datasets[9].data = y10;
myLineChart.stop();
myLineChart.update('none');
}
else
{
console.log("Not enoguh data to plot.....");
}
}
}
};
xhttp.open("GET", "/getfile?s=" + file_min + "&e=" + file_max + "&ge=" + offset, true);
xhttp.send();
}, 100);
}
when chart load it looks like this
enter image description here
after zooming in it looks like this
enter image description here
I have a ColumnSeries chart that looks like this:
When I hover a bar I want it to change color to #ffe876.
I have tried to add a hoverState but it doesnt work:
// Create a hover state
var hoverState = valueAxis.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
This is my code:
<script>
am4core.ready(function() {
var chart = am4core.create("chartdiv_visits_per_week", am4charts.XYChart);
chart.data = [
{
"x": "31",
"value": 1
},
{
"x": "32",
"value": 2
},
{
"x": "33",
"value": 2
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "x";
categoryAxis.renderer.grid.template.disabled = true;
categoryAxis.renderer.labels.template.disabled = true;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.grid.template.disabled = true;
valueAxis.renderer.labels.template.disabled = true;
// Create series
var series1 = chart.series.push(new am4charts.ColumnSeries);
series1.dataFields.valueY = "value";
series1.dataFields.categoryX = "x";
series1.name = "Human unique";
series1.tooltipText = "Human unique week {categoryX}: {valueY}";
series1.fill = am4core.color("#f2a654");
series1.stroke = am4core.color("#f4b570");
series1.strokeWidth = 0;
// Tooltips
chart.cursor = new am4charts.XYCursor();
chart.cursor.snapToSeries = series;
chart.cursor.xAxis = valueAxis;
}); // end am4core.ready()
</script>
<div id="chartdiv_visits_per_week" style="height: 100px;"></div>
What can I do to make the bar change color when I hover it?
You need to add the state to the series, not the axis.
var hoverState = series1.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
Demo below:
var chart = am4core.create("chartdiv_visits_per_week", am4charts.XYChart);
chart.data = [
{
"x": "31",
"value": 1
},
{
"x": "32",
"value": 2
},
{
"x": "33",
"value": 2
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "x";
categoryAxis.renderer.grid.template.disabled = true;
categoryAxis.renderer.labels.template.disabled = true;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.grid.template.disabled = true;
valueAxis.renderer.labels.template.disabled = true;
// Create series
var series1 = chart.series.push(new am4charts.ColumnSeries);
series1.dataFields.valueY = "value";
series1.dataFields.categoryX = "x";
series1.name = "Human unique";
series1.tooltipText = "Human unique week {categoryX}: {valueY}";
series1.fill = am4core.color("#f2a654");
series1.stroke = am4core.color("#f4b570");
series1.strokeWidth = 0;
// Create a hover state
var hoverState = series1.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
// Tooltips
chart.cursor = new am4charts.XYCursor();
chart.cursor.snapToSeries = series1;
chart.cursor.xAxis = valueAxis;
<script src="//cdn.amcharts.com/lib/4/core.js"></script>
<script src="//cdn.amcharts.com/lib/4/charts.js"></script>
<script src="//cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv_visits_per_week" style="height: 100px;"></div>
I am getting the error 'Error: Argument given to addRows must be either a number or an array' when using the code below. However, when I copy the code that is being exported and hard code it, the data displays correctly. Anyone have any ideas?
The hardcoded version is this:
dataTable.addRows([
[ 'DTR V', null, 'Approval Audience Generation Invitation and Confirmation', new Date(2021, 3, 13), new Date(2021, 5, 15) ],
]);
for(var i = 2; i < countRow; i++) {
for(var ii = 0; ii < countColumn; ii++) {
if (ii == 0) {
theData += "[ '" + a.getDataTable().getValue(i, 0) + "', null, '<div class=\"ggl-tooltip\">" + a.getDataTable().getValue(i, 2) + "</div>', new Date("+ a.getDataTable().getFormattedValue(i, 3) +"), new Date("+ a.getDataTable().getFormattedValue(i, 4) +") ], ";
}
}
dataTable.addRows(theData);
}
I found that if I created variables first, I didn't have the error:
for(var i = 0; i < countRow; i++) {
for(var ii = 0; ii < countColumn; ii++) {
if (ii == 0) {
$project = a.getDataTable().getValue(i, 0);
$toolTip = '<div class="ggl-tooltip">' + a.getDataTable().getValue(i, 2) + '</div>';
$dteStrt = a.getDataTable().getFormattedValue(i, 3);
$dteStrtSplt = $dteStrt.split(",");
$yrS = $dteStrtSplt[0];
$moS = $dteStrtSplt[1];
$daS = $dteStrtSplt[2];
$dteEnd = a.getDataTable().getFormattedValue(i, 4);
$dteEndSplt = $dteEnd.split(",");
$yrS = $dteEndSplt[0];
$moS = $dteEndSplt[1];
$daS = $dteEndSplt[2];
}
}
dataTable.addRows([ [ $project, null, $toolTip, new Date($yrS, $moS, $daS), new Date($yrE, $moE, $daE) ] ]);
}
Problem:
I am unable to perform the check and uncheck action with google visualization table associated checkbox. The checkboxes are generated dynamically based on the query value.(0/1)
Code:
function drawQuestions(queryResponse, table_container_id) {
if (queryResponse.isError()) {
alert('Error in query: ' + queryResponseData.getMessage() + ' ' + queryResponseData.getDetailedMessage());
return;
}
var questionBankResponse = queryResponse.getDataTable();
if (questionBankResponse.getNumberOfRows() === 0) {
alert('Empty rows in query: ' + );
return;
}
var questionDataTable = new google.visualization.DataTable();
questionDataTable.addColumn('string', '');
questionDataTable.addColumn('string', '');
questionDataTable.addColumn('string', '');
var questionDataTableRow = new Array();
var rowCounter;
var questionHeader = questionBankResponse.getValue(0, 0);
for (rowCounter = 0; rowCounter < questionBankResponse.getNumberOfRows() ; rowCounter++) {
var count = 0 * 1;
var chbQuestion;
var questionId = questionBankResponse.getValue(rowCounter, 2);
var questionName = questionBankResponse.getValue(rowCounter, 3);
var answerValue = questionBankResponse.getValue(rowCounter, 4);
var answerOthers = questionBankResponse.getValue(rowCounter, 5);
if (answerValue === null)
answerValue = 0;
if (answerValue.toString() === "1") {
chbQuestion = "<input type=\"checkbox\"" + " id=\"" + questionId + "\" checked=\"true\" />";
}
else {
chbQuestion = "<input type=\"checkbox\"" + " id=\"" + questionId + "\" />";
}
if (isNaN(answerOthers))
txtAnswerOthers = "<input type=\"text\"" + "size=\"100\" id=\"" + questionId + "\"" + " value='" + answerOthers + "' name='" + answerOthers + "' />";
else
txtAnswerOthers = null;
questionDataTableRow[count++] = chbQuestion;
questionDataTableRow[count++] = questionName;
questionDataTableRow[count++] = txtAnswerOthers;
questionDataTable.addRow(questionDataTableRow);
}
for (rowCounter = 0; rowCounter < questionDataTable.getNumberOfRows() ; rowCounter++) {
questionDataTable.setProperty(rowCounter, 0, "style", "width:30px");
questionDataTable.setProperty(rowCounter, 1, "style", "width:100%");
}
var tableObject = new google.visualization.Table(document.getElementById(table_container_id));
tableObject.draw(questionDataTable, { allowHtml: true, 'cssClassNames': cssClasses, width: '100%', sort: 'disable' });
Issue: Checkbox state has not been changed before and after the click.
Referred: Previous answer reference
Finally, I developed a solution for this. Here it is.
First, draw the table using google visualization API then draw the checkbox using HTML dom.
function handleQuestionsSqlQueryResponse(dataQueryQuestionsResponse) {
if (dataQueryQuestionsResponse.isError()) {
alert('Error in query: ' + dataQueryQuestionsResponse.getMessage() + ' ' + dataQueryQuestionsResponse.getDetailedMessage());
return;
}
var dtQuestions = dataQueryQuestionsResponse.getDataTable();
var intNoOfRows = dtQuestions.getNumberOfRows();
for (intRowCounter = 0; intRowCounter < intNoOfRows ; intRowCounter++) {
var tblQuestions = new google.visualization.DataTable();
tblQuestions.addColumn('string', '');
tblQuestions.addColumn('string', '');
var arrQuestions = new Array();
var strQuestionSection = dtQuestions.getValue(intRowCounter, 0);
var strQuestionDetails = dtQuestions.getValue(intRowCounter, 1);
if (strQuestionSection !== null && strQuestionDetails !== null) {
arrQuestions = strQuestionDetails.split(";");
for (var intRowIterator = 0; intRowIterator < arrQuestions.length; intRowIterator++) {
var intCount = 0 * 1;
var tblQuestionsRow = new Array();
var strQuestionNo = arrQuestions[intRowIterator].split("|")[0];
var strQuestionName = arrQuestions[intRowIterator].split("|")[1];
tblQuestionsRow[intCount++] = strQuestionName;
if (strQuestionName === "Other / Unknown? Please Describe:") {
tblQuestionsRow[intCount++] = "<input type=\"text\"" + "size=\"30\" id=\"" + strQuestionNo + "Others" + "\"" + " value='' name='" + strQuestionNo + "' disabled />";
} else {
tblQuestionsRow[intCount++] = null;
}
tblQuestions.addRow(tblQuestionsRow);
}
var tableObject = new google.visualization.Table(document.getElementById(strQuestionSection));
tableObject.draw(tblQuestions, { allowHtml: true, 'cssClassNames': cssClasses, width: '100%', sort: 'disable' });
}
}
for (intRowCounter = 0; intRowCounter < intNoOfRows ; intRowCounter++) {
var intQuestionValue = 0;
var strQuestionSection = dtQuestions.getValue(intRowCounter, 0);
var strQuestionDetails = dtQuestions.getValue(intRowCounter, 1);
var tblContainer = document.getElementById(strQuestionSection);
var tblReference = tblContainer.getElementsByTagName('TBODY')[0];
arrQuestions = strQuestionDetails.split(";");
for (var intRowIterator = 0; intRowIterator < arrQuestions.length; intRowIterator++) {
var tblRow = tblReference.rows[intRowIterator];
var tblCheckBox = tblRow.insertCell(0);
var strQuestionNo = arrQuestions[intRowIterator].split("|")[0];
if (strQuestionNo !== null) {
tblCheckBox.innerHTML = "<input type=\"checkbox\"" + " id=\"" + strQuestionNo + "\" name=\"" + strQuestionNo + "\" value=\"" +
intQuestionValue + "\" onchange=\"doCheckOrUnCheck('" + strQuestionNo + "');\" />";
}
}
}
}
I'm trying to build a countdown with Famous Timer.
As a first step, I want to make a scrolling digit, so I made 3 digits which are doing the needed animation and now I need to show only the middle one.
I saw the clipSize option, but couldn't understand how to use it.
If there are some other way to do it, that's great too.
My app is here: http://slexy.org/view/s2R8VNhgEO
Thanks, Alex A.
Rather than fix your code, I wrote an example of how you can create the effect you are looking for with the Lightbox render controller and clipping the view to only show the current count down index. Of course, this can be improved as needed.
Example of the working code in jsBin: Just click to start the counter.
Main Context
var mainContext = Engine.createContext();
var cview = new CountdownView({
start: 10,
size: [50, 50]
});
var counter = 0;
var started = false;
var funcRef;
cview.on('click', function () {
if (started) {
Timer.clear(funcRef);
started = false;
} else {
started = true;
funcRef = Timer.setInterval(function(){
console.log('setNext ' + cview.nextIndex);
cview.setNext();
},1000);
}
});
var container = new ContainerSurface({
size: [100, 100],
properties: {
overflow: 'hidden'
}
});
container.add(cview);
mainContext.add(container);
CountdownView
function CountdownView(options) {
View.apply(this, arguments);
this.options.start = options.start || 10;
this.surfaces = [];
for (var i = 0; i <= this.options.start; i++) {
var surface = new Surface({
size: this.options.size,
content: i.toString(),
properties: {
backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
lineHeight: this.options.size[1]+"px",
textAlign: "center",
fontSize: "30px",
cursor:'pointer'
}
});
this.surfaces.push(surface);
surface.pipe(this._eventOutput);
}
this.renderer = new Lightbox({
inOpacity: 0,
outOpacity: 0,
inOrigin: [1, 1],
inAlign: [1, 1],
showOrigin: [0, 0],
inTransform: Transform.translate(0,0,0.0002),
outTransform: Transform.translate(0,this.options.size[1],0.0001),
outOrigin: [1,1],
outAlign: [1,1],
inTransition: { duration: 600, curve: Easing.inCirc },
outTransition: { duration: 1000, curve: Easing.outCirc },
overlap: true
});
this.add(this.renderer);
this.renderer.show(this.surfaces[this.options.start]);
this.nextIndex = this.options.start - 1;
}
CountdownView.prototype = Object.create(View.prototype);
CountdownView.prototype.constructor = CountdownView;
CountdownView.prototype.setNext = function setNext() {
this.renderer.show(this.surfaces[this.nextIndex]);
this.nextIndex = (this.nextIndex -1 < 0) ? this.options.start : this.nextIndex - 1;
};
CountdownView.prototype.setIndex = function setIndex(newIndex) {
if (newIndex < 0 || newIndex > this.countStart) return;
this.renderer.show(this.surfaces[newIndex]);
};
CountdownView.prototype.getLength = function getLength() {
return this.surfaces.length;
};