Image chart-google - javascript

I am trying to get a radar chart from google api similar to below .I could get everything except the equally distributed 0,0.5,1,1.5,2,2.5,3
In my chart currently it takes min value out of the data given and max value ,and divisions between .its so if 6 is my max value and min value is 3. at very centre of circle it is 3 and then next cud be 3.4,and last extreme edge is 6.What change should i make in below code.to get a distribution ( say 0 to 6) evenly.
function drawVisualization() {
var options = {};
// Chart API chart type 'rs' is radar chart
options.cht = 'r';
// set the line colors
options.colors = ['#00FF00'];
// fill the area under the lines
//options.fill = true;
// create a grid for the chart
// options.chg = '25.0,25.0,4.0,4.0';
// options.chxl: '0:|1|2|3|4|5|6';
var arr = [["165q",1.3333333333333],["160q",6],["161q",6.6666666666667],["162q",7],["163q",8],["164q",5]];
//var pi = '\u03C0';
dataTable = google.visualization.arrayToDataTable(arr, true);
// Treat first row as data as well.
var chart = new google.visualization.ImageChart(document.getElementById('visualization'));
chart.draw(dataTable, options);
}
</script>

Try using the axis-range: chxr parameter with the custom axis labels: chxl parameter:
https://developers.google.com/chart/image/docs/chart_params#axis_range
https://developers.google.com/chart/image/docs/chart_params#axis_labels

Related

How to modify google sheet chart color based on cell value using app script

I want to create a dynamic chart that changes the color based on a cell value. I used the example in this answer but it only uses the first color I declared in the legend as seen in this image:
function modifyChart(sheet, newCssColor) {
// Assume there is only one chart on this sheet.
var sheet = SpreadsheetApp.getActive().getActiveSheet();
const charts = sheet.getCharts();
var array = [];
var colorValues = sheet.getRange("G4:G6").getValues();
for(var i = 0; i < colorValues.length; i++){
array.push(colorValues[i][0]);
}
Logger.log(colorValues);
const barBuilder = charts[0].modify().asColumnChart().setColors(array);
sheet.updateChart(barBuilder.build());
}
But here's exactly want to do:
If score <= 49 set bar color to red
Else if score >= 50 and score <= 89 set bar color to orange
else set bar color to green
Just like how the cell background changes because I set rules to it using Conditional Formatting.
Edit: Change the the cell range to match the sample
Each of your categories is a series in your embedded chart.
You want to set the style options of each series individually.
Use setOption() and set the color options for each series.
For example:
EmbeddedChartBuilder.setOption('series.0.color', 'red').setOption('series.1.color', 'orange').setOption('series.2.color', 'green').build()

Slices in pie chart stay the same size when data changes (version=current as of this post)

I have a pie chart that is loaded using the Google JSON schema for charts. The JSON data is created using ajax. All the Google charts work as designed except for one issue with the pie chart.
Example Pie chart data.
Assume that when the pie chart first loads there are four data elements with values that make up four slices in the pie chart:
A = 410
B = 420
C = 900
D = 540
410 + 420 + 900 + 540 = 2270
410/2270 = 0.1806167400881057 = 65.02°
420/2270 = 0.1850220264317181 = 66.61°
900/2270 = 0.3964757709251101 = 142.73°
540/2270 = 0.2378854625550661 = 85.64°
The first time the pie chart is loaded, slice percents and labels with the amounts look fine.
The problem is when the Pie chart data changes. None of the Pie slices change size. The slice data labels change, but the slice degrees do not:
Example updated data
If data changed From: 410 + 420 + 900 + 540 = 2270 To: 410 + 420 + 9 + 540 = 1379
410/1379 = 0.2973168963016679 = 107.03°
420/1379 = 0.3045685279187817 = 109.65°
9/1379 = 0.0065264684554025 = 2.35°
540/1379 = 0.3915881073241479 = 140.97°
So, if the value of "C" changes from 900 to 9, the degree of change is not reflected in slice "C" (and slices A, B, and D) even though there is a considerable percentage difference. I have included an image of this scenario, however, with different data.
The only time the pie slice sizes change is when the slice is clicked to drill down, but there it's the same formatted json file, just different values. I have compared the json data both on load and after the data has changed and find no reason why the pie chart slice sizes should not also change. The only thing I can deduce is I'm doing something wrong with the json or drawing the chart, or the SVG is cached, or the pie chart does not update slice size.
json data
{ "cols":[{"id":"","label":"Title","pattern":"","type":"string"},{"id":"","label":"Dollars","pattern":"","type":"number"},{"id":"","label":"","pattern":"","type":"string","p":{"role":"style"}}],
"rows":[{"c":[{"v":"A","f":"label a"},{"v":410.0,"f":"$410.00"},{"v":"fill-color: #00805D","f":null}]},
{"c":[{"v":"B","f":"label b"},{"v":420.0,"f":"$420.00"},{"v":"fill-color: #00805D","f":null}]},
{"c":[{"v":"C","f":"label c"},{"v":900.00,"f":"$900.00"},{"v":"fill-color: #78EAD3","f":null}]},
{"c":[{"v":"D","f":"label d"},{"v":540.00,"f":"$540.00"},{"v":"fill-color: #F88451","f":null}]}]}
<div id="chart_div"></div>
function drawPieChart(data) {
$('#chart_div').empty();
$('#chart_div').css('cursor','default')
var options = chartOptions();
var v_savings_suffix="";
if(paoDetails.chart.mode.state === "sav") {
v_savings_suffix = " (Savings)";
}
var _options = {
title: v_chart_title + ' ' + v_savings_suffix
}
Object.assign( options, _options );
var wrapper = new google.visualization.ChartWrapper({
chartType: 'PieChart',
dataTable: data,
options: options,
containerId: 'chart_div'
});
// Must wait for the ready event in order to
// request the chart and subscribe to 'onmouseover'.
google.visualization.events.addListener(wrapper, 'ready', onReady);
function onReady() {
google.visualization.events.addOneTimeListener(wrapper.getChart(), 'select', selectHandler);
}
wrapper.draw();
function selectHandler() {
var options=null;
var selectedSlice = wrapper.getChart().getSelection()[0];
if (selectedSlice) {
// get fund code from selected slice
var fundCode = wrapper.getDataTable().getValue(selectedSlice.row, 0);
if(fundCode !== "NAV") {
options = wrapper.getOptions();
if(options.slices) {
paoDetails.chart.mode.breakdown.fundKey = fundCode;
var slice = options.slices;
var keys = Object.keys(slice).map(Number);
if(keys) {
paoDetails.chart.mode.breakdown.show = !paoDetails.chart.mode.breakdown.show;
paoDetails.chart.mode.funds = !paoDetails.chart.mode.funds;
recalcExemp();
}
wrapper.setOptions(options);
wrapper.draw();
}
}
}
}
} // end drawPieChart
The root pie slice issue is not resolved. This may be not a Google pie chart bug entirely, but after playing with the data I can only conclude that the pie chart needs to be refreshed somehow. I will look at the options to clear percentages in my pie chart with each data update. Perhaps if I call my data load 2x, setting the percentages to 0 on the first call and loading data on the second. Ugly but may get me off this issue. Help is appreciated.
I noticed that the pie slice percentages do not change at all when the
pie data changes.
The pie slice percentage for the green slice changed only when I changed the value of the variable while at a debugging breakpoint. I think the issue is that the pie chart percentages are not updating even though the total value of the data has changed.
To note: The chart container is within bootstrap col. The chart JavaScript Literal data is returned from PHP.

HighChart with more than 50 data points breaks

I am trying to create a bubble chart using the JS HighChart in Angular2+. Whenever there are more than 50 data points (bubbles), the graph breaks. There are the correct number of bubbles in the correct positions (x,y plots) with all different colors but the sizes are all the same even though the z-values are all different. (I am outputing the z-values in a tooltip and the z-values are accurate)
This function is how I am passing in data to the high-chart configuration.
setSeries() {
this.objData = []
this.Data.forEach(element => {
var x= element['xVal'];
var y = element['yVal'];
var z = element['zVal'].toFixed(0);
var name = element['seriesName'].trim();
var newData =[{
x:x,
y:y,
z:+z,
}]
// SetSeriesData is how i am creating the obj to pass into series=[] in highchart configuration
if(i<50) //If I comment this condition, the graph breaks. Right now, the graph is working properly
this.setSeriesData(sumData, name, this.objData)
i++
})
this.options.series = this.objData;
this.generateChart();
}
This is my setSeriesData function.
setSeriesData(graphData: any, dataName: any, objData: any){
var obj = {};
obj['name'] = dataName;
obj['data'] = graphData;
obj['events'] = {click: function(e) {
//takes me to another link
}};
objData.push(obj)
}
In the above function, I configured the chart so that when you click the bubble, it takes you to another page. When the data points >50, this click functionality is not working either. In addition, the fillOpacity is not correct.
Just a few things to point out
1. I am using Angular 2+
2. The discovered issues are, fillOpacity, click, and size based on z-value.
3. It works perfectly when the data points are less than 50
How can I fix this?

The scale on the axis doesn't automatically narrow

I'm using chart.js but on some and only some of the graphs it creates the y-axis scale goes from 0-100 when a more appropriate scale might be 80-100. This means all the lines are bunched up at the top.
You can see what I mean if you visit mbi.dajubox.com and select '14 days' under waiting times. When the results come up beneath click the first entry (Calderdale And Huddersfield NHS Foundation Trust) and the graph appears. But the lines are bunched at the top.
If I go down to number 15 though (Stockport NHS Foundation Trust) it scales the axis ok.
The code that generates them is the same
var ctx = document.getElementById("myChart_"+provID).getContext("2d");
var myLineChart = new Chart(ctx).Line(data, {bezierCurve: false, multiTooltipTemplate: "<%= datasetLabel %> - <%= value %>"});
Can any one help me out?
This is because in your data you receive null values to display in the chart. Chartjs's min function is just a wrapper for the Math.min which will treat null as 0.
A fix for this can be to override the helper function calculateScaleRange
Just declare this after you have Chart.js (or apply the small change straight to your Chart.js)
Chart.helpers.calculateScaleRange = function (valuesArray, drawingSize, textSize, startFromZero, integersOnly) {
//Set a minimum step of two - a point at the top of the graph, and a point at the base
var minSteps = 2,
maxSteps = Math.floor(drawingSize / (textSize * 1.5)),
skipFitting = (minSteps >= maxSteps);
var maxValue = Chart.helpers.max(valuesArray),
minValue = Chart.helpers.min(valuesArray.map(function(value){
//using map to create a new array where all nulls are mapped to Infinity so they do not pull the result down to 0
return value === null ? Infinity: value;
}));
................ //lots more code that is part of calculateScaleRange
here is a full example http://jsfiddle.net/leighking2/L9kLxpe1/

Chart.js zeros handling

I'm working with chart.js and to render a doughnut chart. I want to set the initial chart total value to zero so it can render a full " empty" chart. When I instatiate the chart with zeros it does not render. I cannot find how it handle zeros in the developer documentation.
var kPoints = 000;
var mPoints = 000;
var tPoints = 000;
var cPoints = 000;
var doughnutData = [ {
value : kPoints,
color : "#FF8000"
}, {
value : mPoints,
color : "#99CC00"
}, {
value : tPoints,
color : "#0099CC"
}, {
value : cPoints,
color : "#333333"
}, ];
var ctx = $("#profileChart").get(0).getContext("2d");
var myDoughnut = new Chart(ctx).Doughnut(doughnutData);
From reading the source code for Chart.js I've found that the it tries to sum each of the value fields in its datasource before rendering the chart (see the use of segmentTotal here).
To workaround this, use null for all the values and set one (or more) of the data points to a very small, near zero value. I've used a float notation here for one of the values:
var kPoints = null;
var mPoints = null;
var tPoints = null;
var cPoints = 1e-10;
After that, the example below re-renders the chart (after a 3 second delay) with different data values to show a case of the values updating from the default "dark" chart to a filled out version:
setTimeout(function () {
// Generate a new, random value for each of the data points
doughnutData.forEach(function (item) {
item.value = Math.floor((Math.random() * 10) + 1);
});
var ctx = $("#profileChart").get(0).getContext("2d");
var myDoughnut = new Chart(ctx).Doughnut(doughnutData);
}, 3000);
JSFiddle Example: http://jsfiddle.net/MasterXen/6S9DB/3/
Keep a running total of the values when building the doughnut data.
If there are zero data points, or the total value of all data points is zero, then simply inject an extra dummy point with a label like "No Data" along with an either imperceptible (near-zero) value or a dummy value like 1. In either case, you'll end up with a valid chart with a single category like "No Data".

Categories

Resources