PieChart: how to properly fix unreadable tooltip? - html

I'm using Google Charts API v44 and I found something that looks like a bug. At the legend, when name of the entry is too long you can see a tooltip with this name. But in Firefox under Fedora it gets unreadable because the font color and background color are the same:
I decided to use CSS for that, like this: .goog-tooltip { color: white; } and it did the trick, but later I found out that now it got broken on my Mac:
I tried .goog-tooltip { color: white; background-color: black; } but it changes background not of the tooltip itself but his borders.
How to customize font/background colors to make tooltips readable everywhere?
If you need a source code: HTML, JS, CSS

There are a couple options, see following example charts...
chart 0
You can use the tooltip.textStyle configuration option
However, this only lets you style the text with the following options, no background...
color: <string>,
fontName: <string>,
fontSize: <number>,
bold: <boolean>,
italic: <boolean>
chart 1
you can provide your own HTML/CSS by providing a tooltip column in the data
data.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
and setting tooltip.isHtml: true in the options
For more info, see Customizing HTML content...
Examples...
google.charts.load('current', {
callback: function () {
// data table
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 11],
['Eat', 2],
['Commute', 2],
['Watch TV', 2],
['Sleep', 7]
]);
// chart 0
new google.visualization.PieChart(document.getElementById('piechart0')).draw(data, {
title: 'chart 0',
tooltip: {
textStyle: {
color: 'deeppink',
fontName: 'Verdana',
fontSize: 16,
bold: true,
italic: true
}
}
});
// build tooltip column
data.addColumn({type: 'string', role: 'tooltip', p: {html: true}});
for (var i = 0; i < data.getNumberOfRows(); i++) {
data.setValue(i, 2,
'<div class="goog-tooltip"><div class="goog-tooltip-task">' +
data.getValue(i, 0) + '</div><div class="goog-tooltip-value">' +
data.getValue(i, 1) + '</div></div>'
);
}
// chart 1
new google.visualization.PieChart(document.getElementById('piechart1')).draw(data, {
title: 'chart 1',
tooltip: {
isHtml: true
}
});
},
packages: ['corechart']
});
.goog-tooltip {
background-color: black;
padding: 6px 6px 6px 6px;
}
.goog-tooltip-task {
color: cyan;
font-size: 20px;
font-weight: normal;
}
.goog-tooltip-value {
color: gold;
font-size: 16px;
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="piechart0"></div>
<div id="piechart1"></div>

Related

angular ag-grid how to style the header

I am using ag-grid in my angular application and trying to export to excel. I want to style the header row in the excel. Can anyone help me how to achieve this? I tried the below but doesnt seems to be working.
this.excelStyles = [
{
id: 'smallFont',
font: {
fontName:'Calibri',
size: 9
}
},
{
id:'blueBackground',
interior: {
color: 'blue',
pattern: 'solid'
}
}
]
defaultColDef: {
cellClassRules: {
smallFont: (params) => true,
blueBackground: (params) => params.rowIndex == 0
}
}
Thanks
Seting the excelstyle with id 'header' as shown below will set style for the excel headers.
{
id:'header',
interior: {
color: '#002776',
pattern: 'solid'
},
font: {
color: '#ffffff',
fontName: 'Calibri',
size: 9,
bold: true
}
}

Adding a Y Axis to a google stacked column chart

I have been creating column charts using the google chart tool, but am struggling to add a Y axis to my charts. I just need a standard series of values to appear on the axis on the left hand side of the chart.
I am able to create and manipulate the X axis but the Y axis will not appear for some reason. I'm sure there is something simple I am missing here.
Also apologies if the following code is messy, I am pretty new to this.
<head>
<script type = "text/javascript" src = "https://www.gstatic.com/charts/loader.js">
</script>
<script type = "text/javascript">
google.charts.load('current', {packages: ['corechart']});
</script>
<script language = "JavaScript">
function drawChart() {
// Define the chart to be drawn.
var data = google.visualization.arrayToDataTable([
['Year','Orange','Orange2','Blue','Blue2','Green','Green2','Purple','Purple2','Brown','Brown2','Grey', 'Grey2', {role: 'annotation'}],
['2007',0,2,0,0,0,0,0,0,0,0,0,0,''],
['2008',0,0,0,1,0,0,0,0,0,0,1,0,''],
['2009',0,0,0,0,0,0,0,0,0,0,0,0,''],
['2010',0,0,0,1,0,0,1,0,0,0,0,1,''],
['2011',0,0,0,0,0,0,0,0,0,0,0,0,''],
['2012',0,0,0,0,0,0,0,0,1,0,5,0,''],
['2013',0,0,2,0,0,0,0,0,3,0,0,0,''],
['2014',0,0,0,0,0,0,0,0,0,0,0,0,''],
['2015',0,0,0,2,0,0,0,0,1,0,1,0,''],
['2016',0,2,0,0,0,1,0,0,4,0,0,0,''],
['2017',1,0,0,1,0,0,0,2,0,0,0,0,'']
]);
var colors = [
{ color: 'ff884d' },
{ color: 'ffddcc' },
{ color: '3366ff' },
{ color: '99b3ff' },
{ color: '33ff77' },
{ color: 'b3ffcc' },
{ color: 'd633ff' },
{ color: 'f0b3ff' },
{ color: 'e6ccb3' },
{ color: 'ac7339' },
{ color: 'c0c0c0' },
{ color: 'e6e6e6' },
];
var options = {
isStacked:true,
series: colors,
bar: {groupWidth: "90%"},
legend: {position:'top', textStyle: {fontSize: 9}},
chartArea: { width: "100%"},
axes: {
y: {
0: { side: 'left', label: 'Count'}
}}
};
// Instantiate and draw the chart.
var chart = new google.visualization.ColumnChart(document.getElementById('publicbarchart'));
chart.draw(data, options);
}
google.charts.setOnLoadCallback(drawChart);
</script>
</head>
<body>
<div id="publicbarchart" style="width: 900px; height: 300px;"></div>
</body>
Thanks in Advance,
the y-axis is being hidden by chart option --> chartArea: {width: "100%"}
chartArea controls the size of the center section where the bars are,
and does not include the labels on either axis or at the top
use height & width outside of chartArea for the entire chart
if you want to maximize the chart area, then set limits on left, bottom, top, and / or right,
recommend replacing with the following...
height: '100%',
width: '100%',
chartArea: {
top: 32,
left: 32,
bottom: 32,
right: 12,
height: '100%',
width: '100%'
}
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Year','Orange','Orange2','Blue','Blue2','Green','Green2','Purple','Purple2','Brown','Brown2','Grey', 'Grey2', {role: 'annotation'}],
['2007',0,2,0,0,0,0,0,0,0,0,0,0,''],
['2008',0,0,0,1,0,0,0,0,0,0,1,0,''],
['2009',0,0,0,0,0,0,0,0,0,0,0,0,''],
['2010',0,0,0,1,0,0,1,0,0,0,0,1,''],
['2011',0,0,0,0,0,0,0,0,0,0,0,0,''],
['2012',0,0,0,0,0,0,0,0,1,0,5,0,''],
['2013',0,0,2,0,0,0,0,0,3,0,0,0,''],
['2014',0,0,0,0,0,0,0,0,0,0,0,0,''],
['2015',0,0,0,2,0,0,0,0,1,0,1,0,''],
['2016',0,2,0,0,0,1,0,0,4,0,0,0,''],
['2017',1,0,0,1,0,0,0,2,0,0,0,0,'']
]);
var colors = [
{ color: 'ff884d' },
{ color: 'ffddcc' },
{ color: '3366ff' },
{ color: '99b3ff' },
{ color: '33ff77' },
{ color: 'b3ffcc' },
{ color: 'd633ff' },
{ color: 'f0b3ff' },
{ color: 'e6ccb3' },
{ color: 'ac7339' },
{ color: 'c0c0c0' },
{ color: 'e6e6e6' },
];
var options = {
isStacked:true,
series: colors,
bar: {groupWidth: "90%"},
legend: {position:'top', textStyle: {fontSize: 9}},
axes: {
y: {
0: { side: 'left', label: 'Count'}
}
},
height: '100%',
width: '100%',
chartArea: {
top: 32,
left: 32,
bottom: 32,
right: 12,
height: '100%',
width: '100%'
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

how to call ajax function to update the Highcharts graph dynamically?

I am using Highcharts to plot the graph of temperature vs time. I am having a JSON file wherein data from the backend keep updates the JSON file. I want to call ajax function such that the graphs automatically generates with respect to time. How to do that? I am new to high charts, please help me.
You can use Series.addPoint method.
http://api.highcharts.com/highcharts/Series.addPoint
Here is a example of using Highcharts with live data with GET HTTP requests.
const options = {
chart: {
type: 'spline'
},
title: {
text: 'Live Bitcoin Price'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: 'Price (USD)'
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Live Bitcoint Price [USD]',
data: []
}]
}
const chart = Highcharts.chart('container', options)
// Data
const getData = () => {
setInterval(() => {
window.fetch('https://api.cryptonator.com/api/ticker/btc-usd').then((response) => {
return response.json()
}).then((data) => {
chart.series[0].addPoint({ x: data.timestamp * 1000, y: Number(data.ticker.price) })
})
}, 3000)
}
getData()
#import 'https://code.highcharts.com/css/highcharts.css';
.highcharts-background {
fill: #222;
}
.highcharts-title,
.highcharts-axis-title {
fill: #DDD;
}
.highcharts-credits,
.highcharts-credits:hover {
fill: #222;
}
body {
background-color: #222;
margin 0 !important;
}
#container {
margin: 0;
padding: 0;
border: 0;
background-color: #222;
min-height: 400px;
height:95%;
width:95%;
position:absolute;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
Live example:
https://jsfiddle.net/xpfkx91w/

CSS: content scaling in parent div

I'm using famo.us for rendering surfaces contaning HTML. I want the HTML content to scale with transformations on the surface. For example a "polaroid" rendering with picture and name:
HTML:
<div id="contentdiv" style="width:164px; height:199px; background-color: aqua; border: dashed">
<div class="polaroid">
<img class="img-responsive" src='https://dl.dropboxusercontent.com/u/7197720/www/Serge.jpg'>
<p>Serge</p>
</div>
</div>
CSS:
.polaroid {
position: relative;
width: 100%; /* width 144px, both sides 10px border */
}
.polaroid img {
max-width: 100%;
border: 10px solid #fff;
border-bottom: 2.4vw solid #fff;
-webkit-box-shadow: 3px 3px 3px #777;
-moz-box-shadow: 3px 3px 3px #777;
box-shadow: 3px 3px 3px #777;
}
.polaroid p {
position: absolute;
text-align: center;
width: 100%;
bottom: 0px;
font: 400 1vw 'Kaushan Script', cursive;
color: #888;
}
I just don't get the CSS in a shape that when I enlarge or minimize the div, the content scales with it. To test scaling within a div I created a simple test harness with the example I try to implement. See http://codepen.io/svdoever/pen/raGjrZ. Problem is the scaling/positiong of fonts and that borders should scale on resize, so smaller border on smaller size.
My first question is: is it possible to write html/css that scales correctly with the parent container? Should work for images, fonts, margins etc. Is there a solution for my example?
My second question is: is it possible to make the html/css responsive, so show less/more content based on the size of the container element.
My third question is: what are the best practices for writing this type of html/css.
EDIT: I found blogpost http://blog.sathomas.me/post/zooming-html-content-with-css-scale-transform, but don't really understand the approach yet...
There is a solution for what you have done in your codepin using Famo.us. I have created an example, but will not include all the features of your codepen, but it will give you a start for dynamic css in Famo.us
Answer to first question:
It is possible to write css that will scale proportionately in your event handlers.
Example jsBin of code below
var mainContext = Engine.createContext();
mainContext.setPerspective(1000);
var splash = new Surface({ content: 'Famo.us Application'});
mainContext.add(splash);
var proportion = 1;
var orig = 144;
var min = 100;
var max = 1440;
var widthLabel = new Surface({
content: 'Width',
size: [true, true]
});
var widthSlider = new InputSurface({
type: 'range',
value: orig,
attributes: {
min: min,
max: max
}
});
var heightLabel = new Surface({
content: 'Height',
size: [true, true]
});
var heightSlider = new InputSurface({
type: 'range',
value: orig,
attributes: {
min: min,
max: max
}
});
function _changeProportions() {
var value = widthSlider.getValue();
polaroidMod.setSize([value,value]);
proportion = value/orig ;
polaroidText.setOptions({properties: {fontSize: Math.round(proportion) + 'em'}});
image.setOptions({
properties: {
border: Math.round(proportion*10) + 'px solid #fff',
borderBottom: Math.round(proportion * 1.5) + 'em solid #fff',
boxShadow: Math.round(proportion*3) + 'px ' + Math.round(proportion*3) + 'px ' + Math.round(proportion*3) + 'px #777'
}
});
polaroidText.mod.setTransform(Transform.translate(0,-Math.round(proportion*15), 0.002));
}
widthSlider.on('input', function(e){
var slider = e.target;
heightSlider.setValue(slider.value);
_changeProportions(slider.value);
});
heightSlider.on('input', function(e){
var slider = e.target;
widthSlider.setValue(slider.value);
_changeProportions();
});
var widthNode = mainContext.add(new Modifier({
size: [200, 40],
transform: Transform.translate(0,20, 0.001)
}));
var heightNode = mainContext.add(new Modifier({
size: [200, 40],
transform: Transform.translate(210,20, 0.001)
}));
widthNode.add(widthLabel);
widthNode.add(widthSlider);
heightNode.add(heightLabel);
heightNode.add(heightSlider);
var polaroidMod = new Modifier({
size: [orig, orig],
transform: Transform.translate(10,70, 0.001),
proportions: [1, 1]
});
var polaroidNode = mainContext.add(polaroidMod);
var polaroid = new ContainerSurface({
size:[undefined, undefined]
});
var image = new ImageSurface({
size:[undefined, true],
content: 'https://dl.dropboxusercontent.com/u/7197720/www/Serge.jpg',
properties: {
maxWidth: '100%',
border: Math.round(proportion*10) + 'px solid #fff',
borderBottom: Math.round(proportion) + 'em solid #fff',
boxShadow: '3px 3px 3px #777'
}
});
polaroidNode.add(polaroid);
polaroid.add(image);
polaroidText = new Surface({
size: [true, true],
content: 'Serge',
properties: {
font: "400 "+ Math.round(proportion) +"em 'Kaushan Script', cursive",
color: '#888',
fontSize: Math.round(proportion) + 'em'
}
});
polaroidText.mod = new Modifier({
origin: [0.5, 0],
align: [0.5, 1],
transform: Transform.translate(0,-15, 0.002)
});
var textNode = polaroidNode.add(polaroidText.mod);
textNode.add(polaroidText);
Answer to second question:
Yes, you could make it responsive within your transition event handlers as in the example.
Answer to third question:
Best practice in my opinion is based on use case, but you can see that styling can be dynamic during transitions without using a style sheet file.

Redactor.js List editing causes Chrome to crash, cpu goes to 100%

We are using Redactor.js as a rich text editor.
Admittedly, we are using it on a rather complex webpage, but we have everything working fine, except...
Steps to reproduce
(1) selecting all three of these items inside of a redactor contenteditable div:
item 1
item 2
item 3
(2) select to convert the three items into a unordered list. On redactor's website it converts the items to:
item 1
item 2
item 3
On our site, the Chrome tab becomes unresponsive and cpu usage goes to 100%, yet Chrome never officially close or crashes the tab. Tab remains until you force quit the process.
What happens in the JS code
Inside the redactor.js source (version 10.0.2) the unordered list handler calls the list toggle function on line 4232. As that function runs, it determines that a list needs added and a list needs removed (line 4251). It then runs the list remove function (line 4356) which runs:
document.execCommand('insert' + cmd);
the variable cmd equals the string "unorderedlist" and Chrome stops working (on our site, not on redactor's website).
What are the differences?
Changes to the redactor configuration seem to have no effect on the issue. None the less, here is our redactor.js config object:
$this.redactor({
allowedTags: ['a', 'abbr', 'acronym', 'address', 'article', 'aside', 'b', 'big', 'blockquote', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'i', 'img', 'label', 'legend', 'li', 'marquee', 'ol', 'option', 'p', 'pre', 'q', 's', 'samp', 'section', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'tt', 'u', 'ul', 'var', 'wbr'],
buttons: ['formatting', 'bold', 'italic', 'link', 'orderedlist', 'unorderedlist', 'outdent', 'indent'],
cleanOnPaste: true,
clipboardImageUpload: false,
dragImageUpload: false,
dragFileUpload: false,
formatting: ['p', 'h1', 'blockquote', 'pre'],
imageEditable: false,
imageLink: false,
imagePosition: false,
imageResizable: false,
linkTooltip: true,
placeholder: self.config.placeholder,
removeAttr: [
['blockquote', 'class'],
['h1', 'class'],
['ol', 'class'],
['p', 'class'],
['ul', 'class']
],
removeComments: true,
removeDataAttr: true,
removeEmpty: ['blockquote', 'em', 'h1', 'ol', 'p', 'pre', 'span', 'strong', 'ul'],
replaceTags: [
['big', 'strong'],
['strike', 'del']
],
tabKey: true,
toolbarExternal: '#mceTextTools' + index,
blurCallback: function(e) {
},
changeCallback: function() {
},
clickCallback: function(e) {
},
focusCallback: function(e) {
},
keyupCallback: function(e) {
},
pasteCallback: function(html) {
},
pasteBeforeCallback: function(html) {
},
modalOpenedCallback: function (name, modal) {
},
initCallback: function() {
}
});
Also, we have some suspicion that the problem may be due to some specific CSS rule that does not react well to document.execCommand. Here are the computed styles we are using on s.
ul {
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
color: rgb(68, 68, 68);
cursor: auto;
display: block;
font-family: Georgia, Cambria, 'Times New Roman', serif;
font-size: 18px;
height: 32px;
line-height: 32.4000015258789px;
list-style-type: disc;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
padding-bottom: 0px;
padding-left: 20px;
padding-right: 20px;
padding-top: 0px;
width: 688px;
word-wrap: break-word;
}
li {
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
color: rgb(68, 68, 68);
display: list-item;
font-family: Georgia, Cambria, 'Times New Roman', serif;
font-size: 18px;
height: 32px;
line-height: 32.4000015258789px;
list-style-type: disc;
margin-top: 0px;
text-align: left;
width: 648px;
word-wrap: break-word;
}
Any ideas would be very much appreciated!
The only solution we can find is to add this to the beginning of the list toggle function (line 4235):
var test = this.selection.getNodes();
_.each(test, function(v){
if (v.tagName === 'BR'){
this.selection.selectElement(this.selection.getBlocks()[0]);
}
});
The problem appears to be with this.selection.getCurrent(). Sometimes when BRs are present in the selection, getCurrent() does not return a proper document node. Resetting the selection with the code above prevents Chrome from crashing, but also slightly changes the behavor of the ordered/unorderd list buttons.
This is the response from Redactor's support:
Thanks for reaching out. Unfortunately, I'm unable to reproduce the issue at http://imperavi.com/redactor. I suspect there may be some sort of conflict somewhere in your code.
Please let me know if you have any questions.