I am making a diagram that should show states in a timeline like diagram. I figured that the best fit for it would be horizontal bar diagram, I added data like this:
series: [{
data: [?],
name: 'state1'
}, {
data: [?],
name: 'state2'
}, {
data: [?],
name: 'state3'
}, {
data: [?],
name: 'state1'
}, {
....
}, {
data: [?],
name: 'state1'
}]
Here's what I'v got:
The chart looks like what I need, but I need to somehow group legends, for example this case there should be only 3 legends: state1, state2, state3.
How can I achieve something like this?
I would suggest a different approach, using the column range series type.
This way you can do this with only three series, with a data point for each time slot, rather than a series for each time slot. This saves from having to manipulate the legend or fake other series level actions.
This is an example I did for an earlier question that demonstrates the method (with only two states):
http://jsfiddle.net/jlbriggs/o9ck2zLn/0/
can easily be adapted to use a datetime axis as well, which it seems you might be going for.
Basing on the answer of #StAlex, I would recommend a similar solution, but without the ECMAScript 5 specific forEach:
var legend = {};
for (var i = 0; i < series.length; i++) {
var bar = series[i];
if (!legend[bar.name]) {
legend[bar.name] = 0;
}
legend[bar.name] += bar.data;
}
I assumed that data is a number. If this is not so, add a comment.
var legends = {};
series.forEach(function(bar){
legends[bar.name] = bar.data;
});
Related
Can someone help me solve this problem..
I'm trying to set Chartist pie chart data dynamically. I have a list of projects I'm displaying in a list. Each project has a chart with some information about the project like funding etc. When I try setting the "value" of my chartData, it refuses to detect my values as numbers. Below is an example:
//Chartist data object
fundingData: {
series: [{
value: 0,
name: 'public funding',
className: 'some-class'
}, {
value: 0,
name: 'private funding',
}]
}
//param: project is an object I'm passing
setChartData(project) {
let x = Math.round(project.pro_amount); //
console.log(x); // This prints the amount
this.fundingData.series[0].value = x; // doesn't get assigned
this.fundingData.series[0].value = 12; // gets assigned
}
What am I doing wrong?.. hope my problem is clear enough
Probably all is good, but Chartist isn't reactive. You must call update function after assign:
https://gionkunz.github.io/chartist-js/api-documentation.html#chartistbase-function-update
This is in continued to my question here
I was having a lot of problems in creating highcharts basic charts using CSV data from my local filesystem without using a server/framework and just basic HTML/CSS/JS etc
So, finally, I got an idea to create a chart inside "d3.csv" function wherein we can add highchart functions insdie d3.csv ones
But, there seems to be something very silly wrong, I'm trying with a very basic code and table.
HTML code has only container div element,
Javascript
d3.csv("test.csv", function(data) {
data.forEach(function(d) {
name = d.name,
apples = +d.apples
});
console.log(data[2]);
dataset = data;
//display();
console.log(dataset[0]);
console.log(dataset[0].name);
function push(a)
{
var filter = [];
for (i=0; i<a.length ; i++)
{
filter.push(a[i].apples);
//console.log (filter);
}
return filter;
}
window.apples = push(dataset);
console.log(apples);
$(function () {
$('#container').highcharts({
chart: {
type : 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: [dataset[0].name, dataset[1].name]
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
data: apples
}
]
});
})
});
test.csv :
name,apples
John,8
Jane,3
My console is showing "apples" correctly as [8,3]. I'm getting an empty graph on screen with only axes shown and nothing inside and also, x axis and y axis elements are interchanged.
What am I doing wrong here? Is the global variable - apples, not being accessed inside highcharts fucntions?
UPDATE :
Found the answer, but only one number is showing up.
I have 2 more questions :
How do I show the whole series?
Is this a good method to draw highcharts or will I face many issues later?
Found the solution to this, myself, for a change.
Highcharts will expect function to be parsed in their format ( Highcharts error 14 in console)
Changed my function above to this,
for (i=0; i<a.length ; i++)
{
x = a[i].apples;
y = parseFloat(x)
filter.push(y);
}
return filter;
}
window.apples = push(dataset);
And the series part to this :
series: [{
data : [apples]
}
]
This is finally, giving me a graph with one bar (John, 8) now!!
The second number is still not being loaded, if someone wants to help with that, please comment below.
Update :
changed
data : [apples] -> data: apples (Correct format)
Credits : PawelFus
I'm trying to make a particular bar chart with D3.js, and I don't find any example who could match. I would code a bar chart with two series (one negative, and one generally positive) disposed on the same line, but not stacked.
I guess that maybe it's not very clear, so I've made this on Highcharts. I want to use D3 to connect the chart with a map I did before.
So, does someone know any example that could help me? Can I sort directly the chart even if my series are unordered? And if the two series are punctually postive, does the little one appear in front of the largest?
The trick is to order your data, in order to do so, you can use the [d3.ascending()][1] functions:
with the following example data:
data = [{
name: "A",
valueRight: 1,
valueLeft: 2
}, {
name: "B",
valueRight: 4,
valueLeft: 5
}, ...]
We would have:
function leftBound(node) {
return d3.max([node.valueLeft,-node.valueRight])
}
function rightBound(node) {
return d3.max([node.valueRight,-node.valueLeft])
}
dataSort = function(a,b) {
res = d3.descending(leftBound(a),leftBound(b))
if(res==0) {
return d3.descending(rightBound(a),rightBound(b))
} else {
return res
}
}
For reusable charts, you can also use [selection.sort()][2] but you have to do this for the 2 bar categories.
JsFiddle: http://jsfiddle.net/vgZ6E/55/
ScreenShot:
The original code is from the following question: d3.js bar chart with pos & neg bars (win/loss) for each record
I wanted to plot 2 data series.
The first one is a dynamic series of events which has time and height (water level).
The second is a maximum height from t=0 till indef.
I want the first data series with points and the second without points (since it is just a warning line).
So far i tried the following:
pl_data[0].data = plot_data;
pl_data[1].data = plot_maxHeightCoords;
var pl_options = { series: {
lines: { show: true },
points: { show:[true,false] }
}
};
$.plot("#placeholder_flot", pl_data, pl_options);
and this:
pl_options.points:[true,false];
This however wont work. It worked for colors so i figured it should for points too.
I read the documentation but could not find a hint to fix this.
Thank you for any help!
Not sure I'm following your question but I think you want to configure each series separately and not within your plot options.
If the objects are already created:
pl_data[0].data = plot_data;
pl_data[1].data = plot_maxHeightCoords;
pl_data[0].points = {};
pl_data[0].points.show = true;
pl_data[1].points = {};
pl_data[1].points.show = false;
Or recreate the data object:
var pl_data = [ {data: plot_data, points: {show: true}, lines: {show: true}},
{data: plot_maxHeightCoords, points: {show: false}, lines: {show: true}} ];
$.plot("#placeholder_flot", pl_data, {});
This is discussed under the data format section of the documentation.
I am currently using Highcharts in my website. In one of my charts (a Basic Column chart) I have multiple series, which I can click on the name displayed on the bottom to show/hide.
I can have a lot of series and I would like to limit the number of series to 3 at the same time. It means when it loads the graph, it shows only 3 series and the others are not shown. If I click on a 4th serie, one of the 3 originally present will disappear, so that the number of active serie always remain 3.
I've been looking for it and I found out I needed to do some modifications in the plotOptions.series field and I digged into the Highcharts API reference but didn't found what I wanted. My first attempt at the code would be something like this :
$('#container').highcharts({
plotOptions:{
series: {
var series = this.series;
var nb_of_visible_series = 0;
//Here i count the number of visible series
for(var i=0; i<series.length; i++) {
if(series[i].visible) {
nb_of_visible_series++:
}
}
//If too many series are visible I'll randomly
//hide as many series as necessary
if(nb_of_visible_series>3) {
var nb_of_series_to_hide = nb_of_visible_series-3;
while(nb_of_series_to_hide>0) {
var i=Math.floor(Math.random()*series.length);
if(series[i].visible) {
series[i].hide()
nb_of_series_to_hide--;
}
}
}
}
}
}
So this is the idea but I don't know where to put it for real (not directly in the plotOptions.series field just like this I guess ?). I can put it in plotOptions.series.events.legentItemClick but then it will not be taken into account at the loading of the chart.
I'm looking for some tracks and advices about my code (I'm a JS beginner) and thank you in Advance. And sorry about my poor english.
For sure code you have written wouldn't work. Options for Highcharts should be javascript object, not some thing mixed between variables, options etc.
1) To get displayed on init only three series preprocess data, something like this:
var series = [{ data: [..], name: 'name 1' ..} , { data: [..], name: 'name 2' ..} , ... , {data: [..], name: 'name n'}];
for (var i = 0, len = series.length; i < len; i++) {
series[i].visible = i < 3; //setup variable series.visible to show/hide on init load.
}
$('#container').highcharts({
series: series //pass variable with updated visible option
});
2) As you noticed you need to write your own function for legendItemClick which will check how many series is visible (loop through chart.series and count series.visible == true). Then hide/show specific series using series.hide() / series.show().