Multiple bar chat with Flot with x-axis string - flot

i am using float charts. i faced a problem with multiplebar chart. when i am trying to get x-axis as "string" it shows only single bar. i need to show x-axis ticks in form for sting like city names.HOW CAN I GET MULTIPLE BARS WITH X-AXIS as string?
my code:
$(function () {
var previousPoint;
var d1 = [ ["January", 10], ["February", 8], ["March", 4], ["April", 13], ["May", 17], ["June", 9] ];
var d2 = [ ["January", 5], ["February", 2], ["March", 11], ["April", 2], ["May", 5], ["June", 12] ];
var d3 = [ ["January", 11], ["February", 12], ["March", 6], ["April",8], ["May", 11], ["June",16] ];
var ds = new Array();
ds.push({
data:d1,
bars: {
show: true,
barWidth: 0.2,
order: 1,
lineWidth : 2
}
});
ds.push({
data:d2,
bars: {
show: true,
barWidth: 0.2,
order: 2
}
});
ds.push({
data:d3,
bars: {
show: true,
barWidth: 0.2,
order: 3
}
});
//tooltip function
function showTooltip(x, y, contents, areAbsoluteXY) {
var rootElt = 'body';
$('<div id="tooltip" class="tooltip-with-bg">' + contents + '</div>').css( {
position: 'absolute',
display: 'none',
'z-index':'1010',
top: y,
left: x
}).prependTo(rootElt).show();
}
//Display graph
$.plot($("#placeholder"), ds, {
xaxis: { mode: "categories",
tickLength: 0
} ,
grid:{
hoverable:true
},
});
});

I don't think you can pass strings in as month data. If you want to use months have a look at the flot api - https://github.com/flot/flot/blob/master/API.md
This fiddle might help you as well - http://jsfiddle.net/jSQ2Y/3/
var m1 = {
data : [[1356998400000,14.72]],
bars: { barWidth: 60*60*24*31*1000 }
};
var m2 = {
data : [[1359676800000,30.74]],
bars: { barWidth: 60*60*24*1000 *28 }
};
var m3 = {
data : [[1362096000000,18.57]],
bars: { barWidth: 60*60*24*31*1000 }
};

Related

Echarts, how to change item color based on data array value?

I tried to make scatter graph with Echarts.
Every item has x, y, size, objectid attributes and based on these data I try to build scatter graph. Here is my code:
// x, y, size, objectid
var orgdata = [
[[200, -200, 10, 2]],
[[400, -300, 20, 1]],
[[400, -400, 20, 2]],
];
// map item color based on objectid
var colormap = [
"#FF0000",
"#00FF00",
"#000FFF",
"#FFF0000",
"#0000FF",
];
option = {
xAxis: {type: 'value', position: 'top', min:0, max: 1000},
yAxis: {type: 'value', min: 0, max: -1000},
series: [],
color: colormap
};
for (let i = 0; i < orgdata.length; i++) {
option.series.push({
data: orgdata[i],
type: 'scatter',
symbolSize: function (data) {
return (data[2]);
},
itemStyle: {
color: colormap[orgdata[i][3]]
}
});
}type here
And
Everything else seems to work, but item color doesn't change based on objectid.
How I should fix a code?

Convert played matches to league table

I play an online FIFA tournament since everyone is safe inside. I want to convert the results to a league table. But I don't know what is the best way to do that.
The data I have is:
matches = [
[{
"homeTeam": "A",
"awayTeam": "B",
"homeGoals": 0,
"awayGoals": 3
},
{
"homeTeam": "D",
"awayTeam": "C",
"homeGoals": 0,
"awayGoals": 3
}],
[{
"homeTeam": "D",
"awayTeam": "B",
"homeGoals": 0,
"awayGoals": 2
},
{
"homeTeam": "A",
"awayTeam": "C",
"homeGoals": 0,
"awayGoals": 1
}]
];
The statistics I want to display are: number of matches played, won, lost & drawn. Goals scored and goals against.
I have a React based web app where I display the results of the matches played.
I host the web app through Firebase so I can use firestore, but is it the best way?
Sure its fine to use Firebase. To do this I would create a class that generates the required data-structure and include the needed functions there to manipulate the data.
League.js
class League {
constructor(matches) {
this.matches = matches;
this.table = {};
}
getStandings() {
this.matches.forEach(match => {
const { homeTeam, awayTeam } = match;
// add teams to the table
if (!this.table[homeTeam]) this.addToTable(homeTeam);
if (!this.table[awayTeam]) this.addToTable(awayTeam);
// increase the played counter
this.increasePlayed([homeTeam, awayTeam]);
// calculate won,lost, drawn
this.setResults(match);
// calculate goalsScored and goalsAgainst
this.setGoals(homeTeam, match.homeGoals, match.awayGoals);
this.setGoals(awayTeam, match.awayGoals, match.homeGoals);
});
// all is done; return the table
return this.table;
}
addToTable(team) {
this.table[team] = {
played: 0,
won: 0,
lost: 0,
drawn: 0,
goalsScored: 0,
goalsAgainst: 0
};
}
increasePlayed(teams) {
teams.forEach(team => this.table[team].played++);
}
setResults(match) {
const {
homeTeam, awayTeam, homeGoals, awayGoals
} = match;
if (homeGoals > awayGoals) {
this.table[homeTeam].won++;
this.table[awayTeam].lost++;
} else if (homeGoals < awayGoals) {
this.table[awayTeam].won++;
this.table[homeTeam].lost++;
} else {
this.table[homeTeam].drawn++;
this.table[awayTeam].drawn++;
}
}
setGoals(team, scored, against) {
this.table[team].goalsScored += scored;
this.table[team].goalsAgainst += against;
}
}
module.exports = League;
Then wherever you need the League, create an instance of it with matches parameter, then simply call getStandings() function to figure and return the table.
app.js
const League = require('./League');
// note that all of the matches objects are flat
const matches = [
{
homeTeam: 'A',
awayTeam: 'B',
homeGoals: 0,
awayGoals: 3
},
{
homeTeam: 'D',
awayTeam: 'C',
homeGoals: 0,
awayGoals: 3
},
{
homeTeam: 'D',
awayTeam: 'B',
homeGoals: 0,
awayGoals: 2
},
{
homeTeam: 'A',
awayTeam: 'C',
homeGoals: 0,
awayGoals: 1
}
];
const league = new League(matches);
const standings = league.getStandings();
console.log(standings);
Now running app.js would output:
{
A: {
played: 2,
won: 0,
lost: 2,
drawn: 0,
goalsScored: 0,
goalsAgainst: 4
},
B: {
played: 2,
won: 2,
lost: 0,
drawn: 0,
goalsScored: 5,
goalsAgainst: 0
},
D: {
played: 2,
won: 0,
lost: 2,
drawn: 0,
goalsScored: 0,
goalsAgainst: 5
},
C: {
played: 2,
won: 2,
lost: 0,
drawn: 0,
goalsScored: 4,
goalsAgainst: 0
}
}
Hope this helps!

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/

How to mark discrete points on a time series graph using D3 / Rickshaw?

I'm using Rickshaw to create a live-updating time series graph.
Here is the demo: http://abhshkdz.github.io/icuvisualanalytics/prototypes/rickshaw.html
The data is in csv format (time,value), and this is the core javascript for the visualization:
var count = 0, index=0;
var margin = {top: 10, right: 10, bottom: 10, left: 10},
width = window.innerWidth - margin.right - margin.left - 100,
height = window.innerHeight - margin.top - margin.bottom - 100;
var graph = new Rickshaw.Graph( {
element: document.querySelector("#chart"),
width: width,
height: height,
renderer: 'line',
min: -300,
max: 500,
preserve: true,
series: new Rickshaw.Series.FixedDuration(
[
{
name: 'ECG',
color: palette.color()
}
],
undefined,
{
timeInterval: 12.5,
maxDataPoints: 400,
timeBase: data[index][count].x
})
})
var x_axis = new Rickshaw.Graph.Axis.Time( { graph: graph } );
var y_axis = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis')
} );
var hoverDetail = new Rickshaw.Graph.HoverDetail( {
graph: graph
} );
graph.render();
setInterval(function () {
if (count == 2397) {
count = 0;
index++;
}
var d = {'ECG': data[index][count+=3].y};
graph.series.addData(d);
graph.render();
}, 12.5);
Now there is another set of data which is generated by an algorithm. That data is also in csv format (time,value). It basically finds the peaks of this plot. Using that data, I want to mark those points on this visualization itself.
As far as I looked, Rickshaw does not natively support multiple series using different renderers (either both have to be line or both scatter plots etc.).
So how should I go about this?
The multi renderer feature was added about a month ago. This example shows how to combine several renderers in one chart. The relevant code of the example:
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'multi',
width: 900,
height: 500,
dotSize: 2,
series: [
{
name: 'temperature',
data: seriesData.shift(),
color: 'rgba(255, 0, 0, 0.4)',
renderer: 'stack'
}, {
name: 'heat index',
data: seriesData.shift(),
color: 'rgba(255, 127, 0, 0.4)',
renderer: 'stack'
}, {
name: 'dewpoint',
data: seriesData.shift(),
color: 'rgba(127, 0, 0, 0.3)',
renderer: 'scatterplot'
}, {
name: 'pop',
data: seriesData.shift().map(function(d) { return { x: d.x, y: d.y / 4 } }),
color: 'rgba(0, 0, 127, 0.4)',
renderer: 'bar'
}, {
name: 'humidity',
data: seriesData.shift().map(function(d) { return { x: d.x, y: d.y * 1.5 } }),
renderer: 'line',
color: 'rgba(0, 0, 127, 0.25)'
}
]
});

display x-axis and y-axis lines with out the grid lines using flot

I am using flot to display bar charts. When I set the tickLength to 0, it hides the vertical and horizontal lines but it also hides the x-axis and y-axis lines. I need the x-axis and y-axis with out the vertical and horizontal grid lines. Is there a way to do this?
Please see the second chart in the image. That is what I want.
This trickier than I thought it would be. The only thing I can come up with is to disable the border and axis lines, than add them back in manually:
$(function() {
var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]];
$.plot($("#placeholder"),
[{data: d2,
bars: {
show: true
}}
],
{
xaxis: {
tickLength: 0
},
yaxis: {
tickLength: 0
},
grid: {
borderWidth: 0,
aboveData: true,
markings: [ { xaxis: { from: 0, to: 10 }, yaxis: { from: 0, to: 0 }, color: "#000" },
{ xaxis: { from: 0, to: 0 }, yaxis: { from: 0, to: 15 }, color: "#000" }]
}
}
);
});
Produces:
Mark answer works but it's a little too hardcoded for his data. This one is a little better:
$(function() {
var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]];
$.plot($("#placeholder"),
[{data: d2,
bars: {
show: true
}}
],
{
xaxis: {
tickLength: 0
},
yaxis: {
tickLength: 0
},
grid: {
borderWidth: 0,
aboveData: true,
markings: [ { yaxis: { from: 0, to: 0 }, color: "#000" },
{ xaxis: { from: 0, to: 0 }, color: "#000" }]
}
}
);
});
Still if your chart starts at a value different than 0 you have to manually change the markings.
Setting
xaxis: { tickLength: 0 }, yaxis: { tickLength: 0 }
will also hide the grid lines.
For the case of a (0,0) origin, you can fake the axes by just drawing bottom and left border lines:
grid: {
borderColor: 'black',
borderWidth: {
top: 0,
right: 0,
bottom: 2,
left: 2
},
...
}
Try to color the lines in white (or your bg-color)
yaxis:
. . .
tickColor: "#cccccc" /* or better "#ffffff" */
. . .

Resources