Adding color through a function in flot graph - colors

Can i add color dynamically by calling through a function passed by the user.
I already have the options variable defined by default, the color which the user passes should sit in the option variable. Is this possible? please help
var options = {
series: {
lines: {
show: true
},
points: {
show: true
},
color: '#00c7ce'--> user should pass dynamically
},
xaxis: {
mode: "time",
tickSize: [1, "month"],
tickLength: 0,
},
yaxis: {
show: false
}
}
};

You should be able to pass a color to the options. Setup your input then use that variable as your color.
<input id="userInput"></input>
var usrColor = $("#userInput").val();
var options = {
series: {
lines: { show: true},
points: {show: true, radius: 4},
color: usrColor
}
};
fiddle - http://jsfiddle.net/Rnusy/4/

Related

X-axis multiple colored label for bar chart using chart.js

I need x-axis labels in different colors, I am using "chart.js". I tried below code but it is not working, just showing single color-
scales: {
xAxes: [{
ticks: {
fontColor: [
'rgba(245,88,97,1)',
'rgba(245,88,97,1)',
'rgba(245,88,97,1)',
'rgba(145,151,163,1)',
'rgba(70,180,220,1)',
'rgba(70,180,220,1)',
'rgba(70,180,220,1)'
]
}
}]
}
Output:
Need:
You can make use of the Plugin Core API. It offers different hooks that may be used for executing custom code. In below code snippet, I use the afterDraw hook to draw text of the same color as the corresponding bar.
chart.data.labels.forEach((l, i) => {
var value = chart.data.datasets[0].data[i];
var x = xAxis.getPixelForValue(l);
ctx.fillStyle = chart.data.datasets[0].backgroundColor[i];
ctx.fillText(l, x, yAxis.bottom + 17);
});
When drawing your own tick labels, you need to instruct Chart.js not to display the default labels. This can be done through the following definition inside the chart options.
scales: {
xAxes: [{
ticks: {
display: false
}
}],
You also need to define some padding for the bottom of the chart, otherwise you won't see your custom tick labels.
layout: {
padding: {
bottom: 20
}
},
Please take a look at the following sample code that illustrates how to change the labels on the x-axis depending on the values.
new Chart('myChart', {
type: 'bar',
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
ctx.save();
ctx.textAlign = 'center';
ctx.font = '12px Arial';
chart.data.labels.forEach((l, i) => {
var value = chart.data.datasets[0].data[i];
var x = xAxis.getPixelForValue(l);
ctx.fillStyle = chart.data.datasets[0].backgroundColor[i];
ctx.fillText(l, x, yAxis.bottom + 17);
});
ctx.restore();
}
}],
data: {
labels: ["-3", "-2", "-1", "0", "+1", "+2", "+3"],
datasets: [{
label: "My First Dataset",
data: [60, 59, 80, 81, 60, 55, 40],
fill: false,
backgroundColor: ['rgba(245,88,97,1)', 'rgba(245,88,97,1)', 'rgba(245,88,97,1)', 'rgba(145,151,163,1)', 'rgba(70,180,220,1)', 'rgba(70,180,220,1)', 'rgba(70,180,220,1)'],
borderWidth: 1
}]
},
options: {
layout: {
padding: {
bottom: 20
}
},
scales: {
xAxes: [{
ticks: {
display: false
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
canvas {
max-width: 300px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>

Text Ellipsis in bubble chart

i'm using bubble chart from Highcharts, the label text inside of the bubbles is dynamic and sometimes can be bigger than the bubble itself,
I wonder if there's a way to make the text ellipsis according to the size of the bubble that contain it?
containerOptions = {
chart: {
type: 'bubble',
renderTo: $(container)[0],
events: {
drilldown: function (e) {
if (!e.seriesOptions) {
var chart = this,
drilldowns = {
'Animals': {
name: 'Animals',
data: [
{name: 'Dogs', y:2, x:10, z: 7, drilldown: true},
{name: 'Cats', y:4, x:12, z: 7}
]
},
'Dogs': {
name:"Dogs",
data: [
{name: 'Pitbull', y:3.7, x:7.6, z: 5, drilldown: false},
{name: 'German shepherd', y:6.7, x:6.9, z: 5, drilldown: false}
]
}
},
series = drilldowns[e.point.name];
chart.showLoading('Loading..');
setTimeout(function () {
chart.hideLoading();
chart.addSeriesAsDrilldown(e.point, series);
}, 1000);
}
}
}
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
style: { color: 'red' },
format: '{point.name}'
}
}
},
series: [{
name: 'Things',
colorByPoint: true,
data: [{
name: 'Animals',
y: 5,
x: 1,
z: 9,
drilldown: true
}, {
name: 'Fruits',
y: 2,
x: 9,
z: 9,
drilldown: false
}
]
}],
drilldown: {
series: [],
drillUpButton: {
relativeTo: 'spacingBox',
position: {
y: 0,
x: 0
}
}
}
}
}
You can loop through the data labels on load/redraw event and add/remove ellipsis according to the bubble's width and text's width.
function applyEllipsis() {
var series = this.series[0];
var options = series.options.dataLabels;
series.points.forEach(p => {
var r = p.marker.radius;
var label = p.dataLabel;
var text = label.text.textStr;
var bbox = label.getBBox(true);
while (bbox.width > 2 * r && text.length !== 1) {
text = text.slice(0, -1);
p.dataLabel.attr({
text: text + '\u2026'
});
bbox = label.getBBox(true);
}
p.dataLabel.align({
width: bbox.width,
height: bbox.height,
align: options.align,
verticalAlign: options.verticalAlign
}, null, p.dlBox);
});
}
Attach the function on load/redraw
Highcharts.chart('container', {
chart: {
type: 'bubble',
events: {
load: applyEllipsis,
redraw: applyEllipsis
}
},
example: http://jsfiddle.net/12d997o4/

Save jvectormap as a png from the browser

Is there a way to save the resultant svg jvectormap as a png? I would like users to be able to click on a save or download button, and be able to download the map in some sort of image format to their desktop.
There are several ways to do this, here is a most efficient way (by using canvg),
here is a working example on JSfiddle..
$(function(){
$('#world-map').vectorMap({
map: 'world_mill_en',
backgroundColor: 'white',
normalizeFunction: 'polynomial',
regionsSelectable: true,
regionsSelectableOne: true,
zoomOnScroll: true,
zoomButtons: true,
regionStyle: {
initial: {
fill: "red",
"fill-opacity": 1,
stroke: "none",
"stroke-width": 0,
"stroke-opacity": 1
},
hover: {
fill: "blue",
"fill-opacity": 1
},
selected: {
fill: "#EC6602",
"fill-opacity": 1
},
selectedHover: {
fill: "#EC6602",
"fill-opacity": 1
}
},
onRegionClick: function(e, country){
var map = $("#world-map").vectorMap("get", "mapObject");
$("#world-map").vectorMap("set", "focus", country);
}
});
});
function saveImage() {
var oSerializer = new XMLSerializer();
var sXML = oSerializer.serializeToString(document.querySelector("#world-map svg"));
canvg(document.getElementById('canvas'), sXML,{ ignoreMouse: true, ignoreAnimation: true })
var imgData = canvas.toDataURL("image/png");
window.location = imgData.replace("image/png", "image/octet-stream");
// You can use http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js
// if you want to force filename.ext
}

Passing arrays to Flot

At the end of a functioning JS I have three arrays of x- and y-coordinates, return [theta_plot, omega_plot, e_plot];, that I would like to send to Flot for plotting:
function myPlot(theta_plot, omega_plot, e_plot) {
"use strict";
function doPlot(position) {
$.plot("#placeholder", [
{
data: theta_plot,
label: "Angle (rad)",
yaxis: 1,
color: "red"
},
{
data: omega_plot,
label: "Angular Velocity (rad/sec)",
yaxis: 2,
color: "green"
},
{
data: e_plot,
label: "Energy (J)",
yaxis: 3,
color: "blue"
}
],
{
yaxes: [
{
font: { color: "red" }
},
{
font: { color: "green" }
},
{
font: { color: "blue" }
},
{ alignTicksWithAxis: position === "left" ? 1 : null }
],
legend: { position: "nw" }
}
);
}
doPlot("left");
}
The outer function is my latest attempt to pass these arrays to Flot, without success. The inner function is obviously Flot. Placing doPlot in my JS produces the desired result, though JSLint complains that they are not defined, as it should. However, for purposes of organization I would like doPlot in my HTML. Question: How do I make doPlot aware of my arrays?
Just replace
function doPlot(position) {
with
function doPlot(theta_plot, omega_plot, e_plot, position) {
and call the new function directly without using the myPlot() function.

Highcharts change crosshairs color by number of visible series

What we are trying to do is to:
display crosshairs only if number of visible series > 1 (color: black)
otherwise disable crosshairs or alternatively set color transparent
Here are our problems:
independent of the number of visible series the crosshairs is not shown for the first hover (but for all subsequent hovers)
our main problem is that the color is not changing although the console.log displays that the color is correctly set due to the number of visible series
Please see the fiddle: example
Thanks for your suggestions!
$(function () {
var chart = new Highcharts.Chart({
chart: {
type: 'area',
renderTo: 'container'
},
title: {
text: 'Historic and Estimated Worldwide Population Growth by Region'
},
subtitle: {
text: 'Source: Wikipedia.org'
},
xAxis: {
categories: ['1750', '1800', '1850', '1900', '1950', '1999', '2050'],
tickmarkPlacement: 'on',
title: {
enabled: false
}
},
yAxis: {
title: {
text: 'Billions'
},
labels: {
formatter: function () {
return this.value / 1000;
}
}
},
tooltip: {
formatter: function () {
// show crosshairs only if visible series >1, else transparent
var nVisible = 0;
for (var i = 0; i < chart.series.length; i++) {
if (chart.series[i].visible) {
nVisible++;
};
if (nVisible > 1) {
break;
};
};
if (nVisible > 1) {
chart.options.tooltip.crosshairs = {
width: 1.5,
dashStyle: 'solid',
color: 'black'
};
} else {
chart.options.tooltip.crosshairs = {
color: 'transparent'
};
};
console.log(chart.options.tooltip.crosshairs.color);
return this.y + ' Billions';
},
backgroundColor: 'rgba(255,255,255,0.95)'
},
plotOptions: {
area: {
stacking: 'normal',
lineColor: '#666666',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#666666'
}
}
},
series: [{
name: 'Asia',
data: [502, 635, 809, 947, 1402, 3634, 5268]
}, {
name: 'Africa',
data: [106, 107, 111, 133, 221, 767, 1766]
}, {
name: 'Europe',
data: [163, 203, 276, 408, 547, 729, 628]
}, {
name: 'America',
data: [18, 31, 54, 156, 339, 818, 1201]
}, {
name: 'Oceania',
data: [2, 2, 2, 6, 13, 30, 46]
}]
});
});
Don't add crosshair in real time, instead when chart is initialized, enable crosshair and then manage color by attr() updating. For example: http://jsfiddle.net/D5DME/3/
Code:
tooltip: {
crosshairs: [{
width: 1.5,
dashStyle: 'solid',
color: 'black'
}, false],
formatter: function () {
// show crosshairs only if visible series >1, else transparent
var nVisible = 0;
for (var i = 0; i < this.series.chart.series.length; i++) {
if (this.series.chart.series[i].visible) {
nVisible++;
};
};
if(this.series.chart.tooltip.crosshairs[0]) {
if (nVisible > 1) {
this.series.chart.tooltip.crosshairs[0].attr({
stroke: 'black'
});
} else {
this.series.chart.tooltip.crosshairs[0].attr({
stroke: 'rgba(0,0,0,0)'
});
}
}
return this.y + ' Billions';
},
backgroundColor: 'rgba(255,255,255,0.95)'
},
It looks to me that the tooltip code is the wrong place to be trying this. I would use the series hide and show event handlers to detect how many series were showing (a simple counter which increments in show and decrements in hide would work).
http://api.highcharts.com/highstock#plotOptions.series.events.hide
You could try the chart setting options depending on the count.
However, I'm not sure that simply settting chart.options.tootlip. will work dynamically the way you want.

Resources