Polymer 2.0 <google-chart> webcomponent Pie Chart with Slices Options throws Error - cannot define toLowerCase of undefined - google-visualization

I am using Polymer 2.0 and "google-chart": "GoogleWebComponents/google-chart#^2.0.0". I have no issues in rendering Pie chart. But when I provide "slices" property in Options then the same chart with same data breaks.
I can't find what I am doing wrong.
Here's the code snippet:
<google-chart
style="height: 300px; width: 100%; align: center;"
id="cashflowCategoryPieChart"
type = 'pie'
options = '{
"backgroundColor": {
"fill" : "transparent"
},
"pieHole": 0.4,
"pieSliceBorderColor" : "none",
"pieStartAngle" : 0,
"pieSliceTextStyle": {
"color": "white"
},
"pieSliceText": "label",
"legend": "none",
"colors": [
"#6a1b9a", "#4a148c", "#ea80fc", "#e040fb",
"#d500f9", "#aa00ff", "#f06292", "#ec407a",
"#e91e63", "#d81b60", "#c2185b", "#ad1457",
"#880e4f", "#ff80ab", "#ff4081", "#f50057",
"#9575cd", "#7e57c2", "#673ab7", "#5e35b1",
"#512da8", "#4527a0", "#311b92", "#b388ff",
"#7c4dff", "#651fff", "#6200ea", "#ba68c8",
"#ab47bc", "#9c27b0", "#8e24aa", "#7b1fa2"
]
}'
data = '{{tranCatPieGraphData}}'
>
</google-chart>
pass the tranCatPieGraphData with value:
var tranCatPieGraphData = [["Category","Amount"],["Transfers",26.979999999999993],["Savings",12],["Restaurants",8.7],["Other Income",1.5]]
It displays the chart correctly. No issues.
Now try to add Slices property in the graph options.
like below and see the error it throws - "cannot read property toLowerCase of undefined".
Non working code here ->
<google-chart
style="height: 300px; width: 100%; align: center;"
id="cashflowCategoryPieChart"
type = 'pie'
options = '{
"backgroundColor": {
"fill" : "transparent"
},
"pieHole": 0.4,
"pieSliceBorderColor" : "none",
"pieStartAngle" : 0,
"pieSliceTextStyle": {
"color": "white"
},
"pieSliceText": "label",
"legend": "none",
"slices" : { 1: {"offset": 0.1, "color": "#1a237e"}, },
"colors": [
"#6a1b9a", "#4a148c", "#ea80fc", "#e040fb",
"#d500f9", "#aa00ff", "#f06292", "#ec407a",
"#e91e63", "#d81b60", "#c2185b", "#ad1457",
"#880e4f", "#ff80ab", "#ff4081", "#f50057",
"#9575cd", "#7e57c2", "#673ab7", "#5e35b1",
"#512da8", "#4527a0", "#311b92", "#b388ff",
"#7c4dff", "#651fff", "#6200ea", "#ba68c8",
"#ab47bc", "#9c27b0", "#8e24aa", "#7b1fa2"
]
}'
data = '{{tranCatPieGraphData}}'
>
</google-chart>

try using the array style definition instead...
//slices -> 0, 1, ...
"slices": [{}, {"offset": 0.1, "color": "#1a237e"}],

Related

Chartjs: Set minimum value for zoom on drag and proper user feedback

I am using Chartjs 4.0.1 and chartjs-plugin-zoom 2.0.0 and my chart look like this:
I have set the drag option to be enabled so the user can draw a rectangle to zoom in. Also I have set the zoom mode to 'x'. So the user can only zoom in on the x axis but not on the y axis.
Now I want to limit how far the user can zoom in, to a timespan of one month. I have managed to do that when using the mousewheel to zoom in. But I dont know how to achive the same when using the drag option. I have it configured like this:
drag:{
enabled: true,
backgroundColor:'rgba(180,180,180,0.4)',
threshold: 25,
}
The threshold seems to be my best option to a limit. However that is in pixels and it only says how wide the drawn rectangle has to be for a zoom to occur.
I am already using the onZoomStart callback to check how far the chart is zoomed in and based on that decide if the user can zoom in even more. But apparently that callback is only executed when zooming by mousewheel but not when dragging. So I think I would need to be able to set the threshold of the drag object dynamically. Does anyone know how to do that?
Also I was wondering, is it possible to change the border color of the rectangle when dragging to show the user if it is big enough for a scroll to occur?
The standard solution seems to be to set a limits:{x:{minRange:...}} option. It took me a while to realise where that option should be inserted.
Below is a code snippet with some data resembling yours and a minRange set to 90 days (so I can skip adjusting the tick interval).
Also, there's a hack that changes the color of the drag rectangle to red if the interval is less than the 90 days. It can easily be adapted to completely reject the zoom for less than the desired interval, instead of the current standard behavior which is to adjust (extend) the interval until it is equal to minRange.
The same in this fiddle.
const nPoints = 400,
t0 = Date.parse("2018-06-02T00:00:00Z"),
dt = 2.5*365/nPoints*24*3600*1000;
const data = Array.from(
{length: nPoints},
(_, i)=>({
"timestamp":(t0+dt*i),
value: 80*Math.sin(i*Math.PI/nPoints)+2*Math.random()
})
);
let mouseMoveHandler = null;
chart = new Chart(document.getElementById("myChart"), {
type: 'line',
data: {
datasets: [{
label: "Count",
//pointStyle: false,
pointRadius: 2,
showLine: true,
fill: true,
tension: 0,
borderColor: '#aa6577',
//pointRadius: 4,
//pointBorderWidth: 1,
//pointBackgroundColor: '#7265ce',
data: data
}]
},
options: {
parsing: {
xAxisKey: 'timestamp',
yAxisKey: 'value'
},
spanGaps: false,
responsive: false,
scales: {
x: {
bounds: 'ticks',
type: 'time',
time: {
unit: 'month',
},
title: {
display: false,
text: 'time'
},
ticks: {
display: true,
color: '#cecece'
}
},
y: {
type: 'linear',
display: true,
min: -10,
max: 140,
ticks: {
autoSkip: true,
color: '#cecece'
},
grid:{
color: ctx => ctx.tick.value === 0 ? '#000' : '#ddd',
lineWidth: ctx => ctx.tick.value === 0 ? 3 : 1,
},
title: {
display: false,
text: 'Count',
align: 'end'
},
}
},
plugins:{
legend:{
display: false
},
zoom: {
zoom: {
drag: {
enabled: true,
backgroundColor:'rgba(180,180,180,0.4)',
},
mode: 'x',
onZoomStart({chart, event}){
const x0 = chart.scales.x.getValueForPixel(event.clientX);
if(event.type==="mousedown"){
mouseMoveHandler = function(e){
if(
Math.abs(chart.scales.x.getValueForPixel(e.clientX) - x0) <
chart.options.plugins.zoom.limits.x.minRange
){
chart.options.plugins.zoom.zoom.drag.backgroundColor = 'rgba(255,180,180,0.4)';
}
else{
chart.options.plugins.zoom.zoom.drag.backgroundColor = 'rgba(180,180,180,0.4)';
}
};
chart.canvas.addEventListener("mousemove", mouseMoveHandler);
chart.canvas.addEventListener("mouseup", function(){
if(mouseMoveHandler){
chart.canvas.removeEventListener("mousemove", mouseMoveHandler);
mouseMoveHandler = null;
}
}, {once: true});
}
},
onZoomComplete({chart}){
if(mouseMoveHandler){
chart.canvas.removeEventListener("mousemove", mouseMoveHandler);
mouseMoveHandler = null;
}
document.querySelector('#zoom').innerText = chart.getZoomLevel().toFixed(1)+'x';
document.querySelector('#xSpan').innerText =
Math.round((chart.scales.x.max-chart.scales.x.min)/24/3600/1000)+'days';
}
},
limits:{
x: {
minRange: 90 * 24* 3600 * 1000
}
}
}
}
}
});
document.querySelector('#resetZoom').addEventListener('click', function(){chart.resetZoom();});
document.querySelector('#xSpan').innerText = Math.round((chart.scales.x.max-chart.scales.x.min)/24/3600/1000)+'days';
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.0.1/chart.umd.min.js"
integrity="sha512-HyprZz2W40JOnIBIXDYHCFlkSscDdYaNe2FYl34g1DOmE9J+zEPoT4HHHZ2b3+milFBtiKVWb4sorDVVp+iuqA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/2.0.0/chartjs-plugin-zoom.min.js"
integrity="sha512-B6F98QATBNaDHSE7uANGo5h0mU6fhKCUD+SPAY7KZDxE8QgZw9rewDtNiu3mbbutYDWOKT3SPYD8qDBpG2QnEg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js">
</script>
<canvas id="myChart" style="height:500px; width: 90vw"></canvas>
<button id="resetZoom">Reset zoom</button> <br>
zoom: <span id="zoom">1x</span><br>
X axis span: <span id="xSpan"></span>

Hide grids in Bar Graph

import React from 'react';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
} from 'chart.js';
import { Bar } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
);
const options = {
responsive: true,
elements: {
bar: {
borderWidth: 2,
},
},
plugins: {
scales: {
x: {
grid: {
display: false
}
},
y: {
grid: {
display: false
}
},
},
legend: {
display: false,
},
title: {
display: false,
// text: 'Top Application Accessed',
},
},
};
const labels = ["a", "b", "c", "d0", "d", "e", "t"];
const v = [8, 10, 15, 2, 4, 11, 17]
const data = {
labels,
datasets: [
{
label: "Total no of errors",
data: v,
backgroundColor: 'blue',
}
],
};
export default function App() {
return <Bar options={options} data={data} />;
}
In the above code All the code inside scales is not having any effect.
I want to hide grids from my chart.
I want to also add some features to my chart but anything I add to this code having no effect in the results.
Instead of full grids I want dotted grid only parallel to x axis.
I also want to add different colors to all the bars.
You have putted your scale condif in the plugins section of the options object. This is incorrect, you need to place the scales section in the root of the options object. Then it will work fine.
So instead of options.plugins.scales.x and options.plugins.scales.y you will get: options.scales.x and options.scales.y

remove size data from Apexchart tooltip

How can I remove the size data from the bottom of the tool tip?
the size data is shown automatically and I would like to remove it from the tool tip area.
this is my tooltip code:
tooltip: {
followCursor: true,
size : false,
marker : false,
color: '<?= $color ?>',
x: {
format: 'dd MMM yyyy'
},
y: {
formatter: function(value, opts) {
return (
'<ul style="list-style-type: none">'+
'<li>'+'BaseRate :'+opts.w.config.series[opts.seriesIndex].data[opts.dataPointIndex][2]+'</li>'+
'<li>'+'CloseRate :'+opts.w.config.series[opts.seriesIndex].data[opts.dataPointIndex][1]+'</li>'+
'<li>'+'OpeningRate :'+opts.w.config.series[opts.seriesIndex].data[opts.dataPointIndex][3]+'</li>'+
'<li>'+'DailyHigh :'+opts.w.config.series[opts.seriesIndex].data[opts.dataPointIndex][4]+'</li>'+
'<li>'+'DailyLow :'+opts.w.config.series[opts.seriesIndex].data[opts.dataPointIndex][5]+'</li>'+
'<li>'+'CloseVolume :'+opts.w.config.series[opts.seriesIndex].data[opts.dataPointIndex][6]+'</li>'+
'</ul>'
)
}
},
shared: false,
},

Chartjs 2: Multi level/hierarchical category axis in chartjs

Is it possible to define a bar chart with a multi level/category axis?
For instance I'd like to display the Region/Province categories like in this Excel chart:
I found this example using multiple xAxes.
xAxes:[
{
id:'xAxis1',
type:"category",
ticks:{
callback:function(label){
var month = label.split(";")[0];
var year = label.split(";")[1];
return month;
}
}
},
{
id:'xAxis2',
type:"category",
gridLines: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
ticks:{
callback:function(label){
var month = label.split(";")[0];
var year = label.split(";")[1];
if(month === "February"){
return year;
}else{
return "";
}
}
}
}
]
The problem is it seems that the two axes are not really linked and the alignment of second axis is based on values instead of aligning in middle of lower level category. this case cause issues
Is there a clean way to achieve this in chart.js?
Update:
I ended up creating a feature request on chartjs.
you can provide value separately for different axis via datesets and provide an object with different configuration option (borderColor, pointBackgroundColor, pointBorderColor) etc, i hope It'll help.
here is the link for the with an update (fiddle you shared) Updated Fiddle
data: {
labels: ["January;2015", "February;2015", "March;2015", "January;2016", "February;2016", "March;2016"],
datasets: [{
label: '# of Votes',
xAxisID:'xAxis1',
data: [12, 19, 3, 5, 2, 3]
},
// here i added another data sets for xAxisID 2 and it works just fine
{
label: '# of Potatoes',
xAxisID:'xAxis2',
data: [9, 17, 28, 26, 29, 9]
}]
}
I hope that solves your problem :)
Hope this helps,
I did a bit of research and couldn't find methods to implement your solution in chartjs. Chartjs has grouped bar charts but not subgrouped bar charts like in your case.
Example: http://jsfiddle.net/harshakj89/ax3zxtzw/
Here are some alternatives,
D3js (https://d3js.org/) can be used to create sub grouped bar charts.Data can be loaded from csv or json. D3 is highly configurable, but you may have to put some effort than chartsjs.
https://plnkr.co/edit/qGZ1YuyFZnVtp04bqZki?p=preview
https://stackoverflow.com/questions/37690018/d3-nested-grouped-bar-chart
https://stackoverflow.com/questions/15764698/loading-d3-js-data-from-a-simple-json-string
ZingChart is a commercial tool and can be used to implement bar charts with sub groupes.
https://www.zingchart.com/docs/chart-types/bar-charts/
But I prefer D3 over this library. because D3 comes under BSD License.
This should work as per your requirement http://tobiasahlin.com/blog/chartjs-charts-to-get-you-started/#8-grouped-bar-chart
The best library I could found to have exactly this feature is Highcharts, this is my implementation:
and here http://jsfiddle.net/fieldsure/Lr5sjh5x/2/ you can find out how to implement it.
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: "container",
type: "column",
borderWidth: 5,
borderColor: '#e8eaeb',
borderRadius: 0,
backgroundColor: '#f7f7f7'
},
title: {
style: {
'fontSize': '1em'
},
useHTML: true,
x: -27,
y: 8,
text: '<span class="chart-title"> Grouped Categories with 2 Series<span class="chart-href"> Black Label </span> <span class="chart-subtitle">plugin by </span></span>'
},
yAxis: [{ // Primary yAxis
labels: {
format: '${value}',
style: {
color: Highcharts.getOptions().colors[0]
}
},
title: {
text: 'Daily Tickets',
style: {
color: Highcharts.getOptions().colors[0]
}
}
}, { // Secondary yAxis
title: {
text: 'Invoices',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '${value}',
style: {
color: Highcharts.getOptions().colors[0]
}
},
opposite: true
}]
,
series: [{
name: 'Daily',
type: 'column',
yAxis: 1,
data: [4, 14, 18, 5, 6, 5, 14, 15, 18],
tooltip: {
valueSuffix: ' mm'
}
}, {
name: 'Invoices',
type: 'column',
data: [4, 17, 18, 8, 9, 5, 13, 15, 18],
tooltip: {
valueSuffix: ' °C'
}
}],
xAxis: {
categories: [{
name: "1/1/2014",
categories: ["Vendor 1", "Vendor 2", "Vendor 3"]
}, {
name: "1/2/2014",
categories: ["Vendor 1", "Vendor 2", "Vendor 3"]
}, {
name: "1/3/2014",
categories: ["Vendor 1", "Vendor 2", "Vendor 3"]
}]
}
});
});
body {
padding: 0px !important;
margin: 8px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://blacklabel.github.io/grouped_categories/grouped-categories.js"></script>
<div id="container" class="chart-container"></div>
But the problem is the library is not free for commercial purposes, and this is the Chartjs implementation, in my case it is look like this:
const data ={"labels":[{"label":"Exams","children":["Wellness Examination"]},{"label":"Surgery","children":["Neuter Surgery"]},{"label":"Vaccines","children":["Bordetella"]},{"label":"Dentistry","children":["Dental Cleaning"]},{"label":"Diagnostics","children":["Other","Pre-Anesthetic","Adult Diagnostics","Pre-Anesthetic Diagnostics","Heartworm & Tick Borne Disease Test"]},{"label":"Treatments/Other","children":["Other","Microchip"]}],"datasets":[{"label":"Consumed","backgroundColor":"red","tree":[{"value":0,"children":["0"]},{"value":0,"children":["0"]},{"value":1,"children":["1"]},{"value":0,"children":["0"]},{"value":15,"children":["0","1","3","11","0"]},{"value":15,"children":["2","13"]}]},{"label":"Purchased","backgroundColor":"blue","tree":[{"value":28,"children":["28"]},{"value":1,"children":["1"]},{"value":24,"children":["24"]},{"value":10,"children":["10"]},{"value":103,"children":["2","16","34","49","2"]},{"value":165,"children":["75","90"]}]}]};
window.onload = () => {
const ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: data,
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Hierarchical Bar Chart'
},
layout: {
padding: {
// add more space at the bottom for the hierarchy
bottom: 45
}
},
scales: {
xAxes: [{
type: 'hierarchical',
stacked: false,
// offset settings, for centering the categorical
//axis in the bar chart case
offset: true,
// grid line settings
gridLines: {
offsetGridLines: true
}
}],
yAxes: [{
stacked: false,
ticks: {
beginAtZero: true
}
}]
}
}
});
};
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/chart.js/dist/Chart.bundle.js"></script>
<script src="https://unpkg.com/chartjs-scale-hierarchical"></script>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
for each more column just add another dataset.

ChartNew.js - Remove/Hide zero label from Pie Chart

I'm trying to remove zero(0) label from pie chart in ChartNew.js.
Can't figure it out.
Below is the example:
var pieData = [
{
value: 0,
color: "sandybrown",
title: "label1",
},
{
value: 10,
color: "gold",
title: "label2",
},
{
value: 46,
color: "darkviolet",
title: "label3",
},
{
value: 0,
color: "green",
title: "label4",
},
{
value: 33,
color: "DeepSkyBlue",
title: "label5",
}
];
var myoptions = {
animateRotate : true,
animateScale : false,
animationByData : false,
animationSteps : 50,
canvasBorders : true,
canvasBordersWidth : 0,
canvasBordersColor : "black",
legend : true,
inGraphDataShow : true,
animationEasing: "linear",
annotateDisplay : true,
spaceBetweenBar : 5,
graphTitleFontSize: 18,
extrapolateMissingData : false
};
var myPie = new Chart(document.getElementById("canvas1").getContext("2d")).Pie(pieData, myoptions);
<SCRIPT src='https://rawgit.com/FVANCOP/ChartNew.js/master/ChartNew.js'></SCRIPT>
<canvas id="canvas1" height="500" width="500"></canvas>
[https://jsfiddle.net/boxxevolution/wb64oL66/2/][1]
Im trying to remove label1 and label4 from the chart.
As suggested by V-Q-A NGUYEN, add the following line in options,
inGraphDataTmpl: "<%=(v6 > 0 ? v6+' %' : ' ')%>",