Echarts - Is possible stack date bar from heightest to tallest? - echarts

This is my actual state
Is possible to stack date from the heightest to the tallest? like this:
Objective state (stacked in the right order)
This is the code example to get my actual state:
series: [
{
name: 'teste1',
type: 'bar',
stack: '1',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: 'teste2',
type: 'bar',
stack: '1',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: 'teste3',
type: 'bar',
stack: '1',
data: [150, 232, 201, 154, 190, 330, 410]
}
]

Yes, you have two options:
Re-sort series data. The usual bar chart use data by horizontal but the stack bar use vertical column. Just arrange columns by ascending. Before: 120, 220, 150, after: 120, 150, 220.
Rebuild data with dataset, with dataset you can remap dimensions as you need.

Related

How to change color of vertical line with google chart candle stick?

I want to change the candlestick chart's color.
When fallingColor.fill and risingColor.fill are set, the vertical line color remains blue like the image.
This is the code I wrote.
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Mon', 20, 28, 38, 45],
['Tue', 31, 38, 55, 66],
['Wed', 50, 55, 77, 80],
['Thu', 77, 77, 66, 50],
['Fri', 68, 66, 22, 15]
// Treat first row as data as well.
], true);
var options = {
legend:'none',
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' }, // red
risingColor: { strokeWidth: 0, fill: '#0f9d58' }, // green
},
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
https://jsfiddle.net/fe26/t6b57vnL/7/
How can I change the color of the line?
you can use the colors option, an array of color strings.
each color in the array, is applied to each series in the data table.
in the example posted, there is only one series, so only one color is needed / allowed.
the colors option will change the color of all the chart elements.
however, the fallingColor & risingColor options will override the colors option.
leaving only the vertical lines the same color as the colors option.
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Mon', 20, 28, 38, 45],
['Tue', 31, 38, 55, 66],
['Wed', 50, 55, 77, 80],
['Thu', 77, 77, 66, 50],
['Fri', 68, 66, 22, 15]
], true);
var options = {
legend:'none',
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' }, // red
risingColor: { strokeWidth: 0, fill: '#0f9d58' }, // green
},
colors: ['magenta']
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
you can also you the style column role.
the style role is added as an additional column to the data table.
set the value of the column to the color / style you want to display for each row.
if the style value is null, it will default back to the above scenario.
however, if it is not null, it will override both options in the above scenario.
note: you will need to provide column headings to use the style role.
var data = google.visualization.arrayToDataTable([
['x', 'low', 'open', 'close', 'high', {role: 'style', type: 'string'}],
['Mon', 20, 28, 38, 45, 'lime'],
['Tue', 31, 38, 55, 66, 'purple'],
['Wed', 50, 55, 77, 80, null],
['Thu', 77, 77, 66, 50, null],
['Fri', 68, 66, 22, 15, 'orange']
]);
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['x', 'low', 'open', 'close', 'high', {role: 'style', type: 'string'}],
['Mon', 20, 28, 38, 45, 'lime'],
['Tue', 31, 38, 55, 66, 'purple'],
['Wed', 50, 55, 77, 80, null],
['Thu', 77, 77, 66, 50, null],
['Fri', 68, 66, 22, 15, 'orange']
]);
var options = {
legend:'none',
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' }, // red
risingColor: { strokeWidth: 0, fill: '#0f9d58' }, // green
},
colors: ['magenta']
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
another option would be to use css, and override the svg elements for the vertical lines,
which are drawn using <rect> elements, with --> width="2"
but I would use this as a last resort.
#chart_div rect[width="2"] {
fill: #000000;
stroke: #000000;
}
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['x', 'low', 'open', 'close', 'high', {role: 'style', type: 'string'}],
['Mon', 20, 28, 38, 45, 'lime'],
['Tue', 31, 38, 55, 66, 'purple'],
['Wed', 50, 55, 77, 80, null],
['Thu', 77, 77, 66, 50, null],
['Fri', 68, 66, 22, 15, 'orange']
]);
var options = {
legend:'none',
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' }, // red
risingColor: { strokeWidth: 0, fill: '#0f9d58' }, // green
},
colors: ['magenta']
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
});
#chart_div rect[width="2"] {
fill: #000000;
stroke: #000000;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
you could also listen for the chart's 'ready' event,
and manually change the chart's svg elements using your own script.
but this is not recommended...

Performance Optimization: SQL query and looping over the grouped object (hash)

My Association is like this
field has_many field_values
field_value belongs_to field
I am querying field_values table to get field_values grouped by field_id like this:
def field_values
FieldValue.where(field_id: #field_ids)
.pluck(:id, :value, :field_id, :active, :old_value)
.map { |obj| { id: obj[0], value: obj[1], field_id: obj[2],
active: obj[3], old_value: obj[4] } }
.group_by { |a| a[:field_id] }
end
Above method executes this SQL which takes 20ms to fetch 30k records
SELECT id, value, field_id, active, old_value FROM field_values WHERE field_id IN (85, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 117, 118, 119);
And then constructing my #shared_fields obj to insert field_values in it:
#shared_fields
{
id: 1
field:
{
id: 11,
field_values:
[
{
id: 111,
value: 'abc',
field_id: 11,
active: true,
old_value: nil
}
{
id: 112,
value: 'pqr',
field_id: 11,
active: true,
old_value: nil
}
]
}
}
def construct_obj
field_values.each do |id, values|
sh_field = #shared_fields.detect { |shf| shf[:field][:id] == id }
next unless sh_field
sh_field[:field][:field_values] = values
end
end
field_values method is taking 20 ms to fetch 30k records
construct_obj method is taking around 170 ms to complete the
processing.
Any thoughts on how we can optimize the sql query and also looping over the grouped object which is taking 170 ms.

How to do Group Stacking available in ng2-charts?

In the original Chart.js the Dataset Structure has a property called stack which can be used to stack group of data sets separately.
"stack: String The ID of the group to which this dataset belongs to (when stacked, each group will be a separate stack)"
I tried doing this in ng2-charts like so:
public barChartData: any[] =[
{
data: [],
label: 'Label',
type: 'bar',
stack: '1'
}
]
But didn't do anything.
Here is the dataset property from the ng2-charts:
datasets (Array<{data: Array | number[], label: string}>) - data see about, the label for the dataset which appears in the legend and tooltips
Is there a work around for stacking groups separately?
Thank you!
You are right about what the documentation says, I'm trying to do the same thing. I tried this as an example, it should work, according to the link : http://www.chartjs.org/docs/latest/charts/bar.html
in my .ts :
public barChartData:any[]=[
{data: [65, 59, 80, 81, 56, 55, 40], label: 'Series A', stack: '1'},
{data: [28, 48, 40, 19, 86, 27, 90], label: 'Series B', stack: '1'},
{data: [42, 24, 71, 14, 31, 49, 30], label: 'Series C', stack: '2'}
];
public barChartLabels:string[] = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
public barChartOptions:any = {
responsive: true,
scales:{
xAxes:[{
stacked:true
}],
yAxes:[{
stacked:true
}]
}
};
public barChartType:string = 'bar';
in my HTML :
<canvas id="chart1" baseChart
[datasets]="barChartData"
[labels]="barChartLabels"
[options]="barChartOptions"
[chartType]="barChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas>
I found this sample of chart.js for grouped stack bar. Unfortunately it's plain JS : https://github.com/chartjs/Chart.js/blob/master/samples/charts/bar/stacked-group.html
EDIT :
use my code above and do npm install chart.js#2.6 --save
-> it worked directly for me
I found this solution while checking if stacks were checked when creating the bars. they weren't in my current version.
So I figured out that the way to do this is to un-stack the yaxis and then add the stack to the dataset property like so:
{
data: [],
label: 'dataset 1',
type: 'bar',
yAxisID: 'bar-y-axis1',
stack: '1'
},
{
data: [],
label: 'dataset 3',
type: 'bar',
yAxisID: 'bar-y-axis1',
stack: '1'
},
{
data: [],
label: 'dataset 4',
type: 'bar',
yAxisID: 'bar-y-axis1',
stack: '1'
},

How to register plot or label click event in chart.js

Now I am using Chart.js lib.
And want to register click event handler to run my custom code.
var lineChart = new Chart(ctx, {
type: 'line',
data: {
labels: label,
datasets: [{
label: "Logined users num",
backgroundColor: "rgba(38, 185, 154, 0.31)",
borderColor: "rgba(38, 185, 154, 0.7)",
pointBorderColor: "rgba(38, 185, 154, 0.7)",
pointBackgroundColor: "rgba(38, 185, 154, 0.7)",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointBorderWidth: 1,
data: data
}]
},
});
I want to run my custom code when I click a label or a plot.
And when click them, how to get information about them.
ex) When I click "2016-11-16" label, how to get "2016-11-16" string value.
ex) When I click plot (2016-11-19,4), how to get plot info?
onCLick Event
Called if the event is of type 'mouseup' or 'click'. Called in the
context of the chart and passed an array of active elements
When you click on point it will call the function by passing two parameters mouseEvent and an array of a chart. From chart array, you can extract the label.
options: {
onClick : function(mouseEvent,chart){
}
}
[Sample-code]
var ctx = document.getElementById("myChart1");
var label = ["January", "February", "March", "April", "May", "June", "July"];
var data = [65, 59, 80, 81, 56, 55, 40]
var lineChart = new Chart(ctx, {
type: 'line',
data: {
labels: label,
datasets: [{
label: "Logined users num",
backgroundColor: "rgba(38, 185, 154, 0.31)",
borderColor: "rgba(38, 185, 154, 0.7)",
pointBorderColor: "rgba(38, 185, 154, 0.7)",
pointBackgroundColor: "rgba(38, 185, 154, 0.7)",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointBorderWidth: 1,
data: data
}]
},
options: {
onClick : function(mouseEvent,chart){
var myLabel = label[chart[0]._index];
var y = this.data.datasets[chart[0]._datasetIndex].data[chart[0]._index];
}
}
});
P.S :- It will only work if you click on chart or points not for label.

Highcharts markers on bar charts

I have made a chart similar to this (http://www.highcharts.com/demo/bar-basic) using Highcharts, and now I would like to add a marker in the form of a vertical line on each of the bars.
I've been trying to use "scatter" but that only allows me to add one marker per group of bars. Is there any way to change that? Or any other solutions? Thanks!
You have two solutions:
use scatter as you said, but calculate x-position (for example two bar series mean -0.25 and +0.25 to x-category. For example [1.25, 200] to show for second bar in second category.
use column range series with minPointLength set: http://jsfiddle.net/7F4hQ/ and stacks to connect series together
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
},
columnrange: {
minPointLength: 5,
borderWidth: 0
}
},
series: [{
stack: 1,
name: 'Year 1800',
data: [107, 31, 635, 203, 2]
}, {
stack: 2,
name: 'Year 1900',
data: [133, 156, 947, 408, 6]
}, {
stack: 3,
name: 'Year 2008',
data: [973, 914, 4054, 732, 34]
}, {
stack: 1,
linkedTo: 0,
type: 'columnrange',
name: 'Year 1800',
data: [ [107, 108], [107, 108],[107, 108], [107, 108],[107, 108] ]
}, {
stack: 2,
linkedTo: 1,
type: 'columnrange',
name: 'Year 1900',
data: [ [107, 108], [107, 108],[107, 108], [107, 108],[107, 108] ]
}, {
stack: 3,
linkedTo: 2,
type: 'columnrange',
name: 'Year 2008',
data: [ [10, 11], [107, 108],[107, 108], [107, 108],[107, 108] ]
}]
I think Bullet Chart is what you were looking for. They might have added this feature in later versions. You can add as many bars as you want.