Related
I want to show the total value and x axis label on top of my stacked bar chart so it look like this
but right now, i'm only can show the total value, i don't know how to add the x axis label, so far mine look like this
i'm also want to custom my tooltip to look like this
Here's my code:
export default {
name: 'BarAllYear',
data() {
return {
BarAllYearData,
};
},
mounted() {
const ctx = document.getElementById('bar-all-year').getContext('2d');
const BarChart = {
type: 'bar',
data: this.BarAllYearData,
plugins: [ChartDataLabels],
options: {
borderWidth: 1,
responsive: true,
plugins: {
legend: {
display: false,
},
tooltip: {
xAlign: 'center',
yAlign: 'bottom',
backgroundColor: '#FFF',
displayColors: false,
titleFont: {
size: 20,
},
bodyFont: {
size: 18,
},
titleColor(tooltipItem) {
const titleLabelColor = tooltipItem.tooltip.labelColors[0].backgroundColor;
return titleLabelColor;
},
bodyColor() {},
},
datalabels: {
color: '#666666',
align: 'top',
anchor: 'end',
offset: 1,
formatter(value, context) {
const sumValue = context.chart.config.data.datasets.map((datapoint) => datapoint.data[context.dataIndex]);
function totalSum(total, datapoint) {
return total + datapoint;
}
const sum = sumValue.reduce(totalSum, 0);
return `${sum}`;
},
font: {
weight: 'bold',
size: 16,
},
},
},
scales: {
x: {
ticks: {
color: 'black',
font: {
weight: 'bold',
size: 16,
},
},
stacked: true,
},
y: {
ticks: {
stepSize: 1,
font: {
size: 18,
},
},
stacked: true,
},
},
layout: {
padding: 20,
},
},
};
/* eslint-disable no-new */
new Chart(ctx, BarChart);
},
};
and this is the BarAllYearData:
const DonutAllYearData = {
labels: [
'Butuh Perhatian Khusus',
'Dalam Proses',
'Selesai',
],
datasets: [{
label: 'My First Dataset',
data: [16, 3, 5],
backgroundColor: [
'#FF7A00',
'#23C4DB',
'#666666',
],
hoverOffset: 4,
}],
};
export default DonutAllYearData;
I'm using vue 3 by the way.
Anyway, thanks for the help
Playing around with eCharts and i'm trying to replicate the graph shown in this tutorial
https://medium.com/#mailjontay/make-a-dynamic-chart-with-react-and-echarts-a-simple-tutorial-92a5c3c053a2
I'm using my own data sets, and both of my .js files are identical format to the ones used in the tutorial.
I'm having an issue with rendering the number of workers on my Yaxis, I'm not receiving any error messages and my data is defined.
My code is as follows:
import React, { Component } from "react";
import ReactEcharts from "echarts-for-react";
import { workForceDataFemale } from "./WorkForceDataFemale";
import { workForceDataMale } from "./WorkForceDataMale";
class App extends Component {
getOption = () => {
let sectors = [];
let years = [];
let workforceObject = [];
let workers = [];
Object.entries(workForceDataFemale).forEach(entry => {
years = [...years, entry[0]];
workforceObject = [...workforceObject, entry[1]];
entry[1].forEach(e => {
workers = [...new Set([...workers, e.n_workers])]
console.log(e.n_workers, "number of workers")
sectors = [...new Set([...sectors, e.sector])];
});
});
let options = years.map(year => {
let obj = {};
obj["series"] = [
{
stack: "group",
data: workForceDataFemale[year]
},
{
stack: "group",
data: workForceDataMale[year]
}
];
obj["title"] = {
text: `Number of workers over time by gender`
};
return obj;
});
return {
baseOption: {
timeline: {
autoPlay: false,
axisType: "category",
bottom: 20,
data: years,
height: null,
inverse: true,
left: null,
orient: "vertical",
playInterval: 1000,
right: 0,
top: 20,
width: 55,
label: {
normal: {
textStyle: {
color: "#aaa"
}
},
emphasis: {
textStyle: {
color: "#333"
}
}
},
symbol: "none",
lineStyle: {
color: "#aaa"
},
checkpointStyle: {
color: "#354EF6",
borderColor: "transparent",
borderWidth: 2
},
controlStyle: {
showNextBtn: false,
showPrevBtn: false,
normal: {
color: "#354EF6",
borderColor: "#354EF6"
},
emphasis: {
color: "#5d71f7",
borderColor: "#5d71f7"
}
}
},
color: ["#e91e63", "#354EF6"],
title: {
subtext: "Data from Sweet Analytics",
textAlign: "left",
left: "5%"
},
tooltip: { backgroundColor: "#555", borderWidth: 0, padding: 10 },
legend: {
data: ["Female", "Male"],
itemGap: 35,
itemHeight: 18,
right: "11%",
top: 20
},
calculable: true,
grid: {
top: 100,
bottom: 150,
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
label: {
show: true,
formatter: function(params) {
return params.value.replace("\n", "");
}
}
}
}
},
xAxis: [
{
axisLabel: {
interval: 0,
rotate: 55,
textStyle: {
baseline: "top",
color: "#333",
fontSize: 10,
fontWeight: "bold"
}
},
axisLine: { lineStyle: { color: "#aaa" }, show: true },
axisTick: { show: false },
data: sectors,
splitLine: { show: false },
type: "category"
}
],
yAxis: [
{
axisLabel: {
textStyle: { fontSize: 10 }
},
axisLine: { show: false },
axisTick: { show: false },
name: "Population",
splitLine: {
lineStyle: {
type: "dotted"
}
},
type: "value"
}
],
series: [{ name: "Female", type: "bar", data: workers }, { name: "Male", type: "bar", data: workers }]
},
options: options
};
};
render() {
return (
<ReactEcharts
option={this.getOption()}
style={{ height: "85vh", left: 50, top: 50, width: "90vw" }}
opts={{ renderer: "svg" }}
/>
);
}
}
export default App;
This is how far i've gotten :
And I'm trying to get to here:
In the series you should add stack you have in each object to add stack: "stackbar" like this :
series: [
{ name: "Female", type: "bar", data: workers, stack: "stackbar" },
{ name: "Male", type: "bar", data: workers , stack: "stackbar"}
]
I'm using angular6 and the office highcharts angular wrapper (https://github.com/highcharts/highcharts-angular) in version 2.4.0.
Everything is working good except the labels that can be placed manually on the chart.
I just don't manage to get them refreshed.
I have a graph that can be filtered through the back-end. When I get the new generated data I update the data in my chartOptions which are used in the html as [options]="chartOptions" for the angular component.
The chartOptions are instanciated from my default class like this: this.chartOptions = new GraphConfigSeqAtteptedVsAchived().chartOptions;
The Class looks like this:
`import * as Highcharts from 'highcharts';
export class GraphConfigSeqAtteptedVsAchived{
public chartOptions: any;
constructor(){
this.chartOptions = {
chart: {
height: 600,
width: 620,
events:{load: function(){
this.myTooltip = new Highcharts.Tooltip(this, this.options.tooltip);
}
},
backgroundColor: 'transparent',
},
credits: {
text: 'charname',
href: ''
},
labels: {
},
exporting:{
chartOptions:{
title: {
text:'not set',
style:{
color: '#000000'
},
margin: 0
}
}
},
tooltip: {
enabled: false
},
xAxis: {
min: -10,
max: 0,
width: 535,
title: {
text: 'Rainfall (mm)',
style: {
fontWeight: "bold",
color: '#000000'
}
},
reversed: true,
tickInterval: 1
},
yAxis: {
min: -10,
max: 0,
title: {
text: 'Rainfall (mm)',
style: {
fontWeight: "bold",
color: '#000000'
}
},
reversed: true,
tickInterval: 1
},
title: {
text: ' as',
margin: 0,
style:{
color: 'transparent'
}
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 90,
floating: true,
backgroundColor: '#FFFFFF',
borderWidth: 1,
navigation: {
enabled: false
}
},
plotOptions: {
scatter: {
stickyTracking: false,
allowPointSelect: true,
marker: {
radius: 3,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '',
hideDelay: 500
},
symbol: "circle",
events: {
mouseOut: function() {
this.chart.myTooltip.hide();
this.chart.myTooltip.options.enabled = false;
},
mouseOver: function() {
if(this.halo) {
this.halo.attr({
'class': 'highcharts-tracker'
}).toFront();
}
},
click: function(event) {
this.chart.myTooltip.options.enabled = true;
this.chart.myTooltip.refresh(event.point, event);
}
}
},
line:{
events: {
legendItemClick: function () {
return false;
}
}
},
series:{
allowPointSelect: true
}
},
series: [{
type: 'line',
data: [[30, 30], [-30, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 1
}
},
showInLegend: false,
color: "rgba(0, 0, 0, 0.6)",
enableMouseTracking: false
},{
type: 'line',
data: [[30, 29.5], [-29.5, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(125, 162, 159, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[29.5, 30], [-30, -29.5]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(125, 162, 159, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[29, 30], [-30, -29]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(197, 144, 161, 0.35)",
enableMouseTracking: false
},{
type: 'line',
data: [[30, 29], [-29, -30]],
marker: {
enabled: false
},
states: {
hover: {
lineWidth: 0
}
},
showInLegend: false,
dashStyle: 'ShortDash',
color: "rgba(197, 144, 161, 0.35)",
enableMouseTracking: false
}]
}
}
}`
The generated data is in the typescript dynamically added and all of that works just fine. Everything is refreshed after I set the updateFlag for [(update)]="updateGraph". The axis titles are also fine.
The only thing that's not refreshed for me are the labels i dynamically added to the chart like this:
let labelTotalNumberOfEyes = {
html : this.translate.instant('GRAPHS.TOTAL_NUMBER_OF_EYES') + ': ' + (scatterSeries.data.length + scatterSeriesRetreatment.data.length),
style : {
left : '330px',
top : '368px',
fontSize : '14px',
backgroundColor: '#FFFFFF',
borderWidth: 1,
}
}
this.chartOptions.labels.items.push(labelTotalNumberOfEyes);
Does someone have any idea what I'm might doing wrong? I don't see any further option than just setting this update flag and it works fine for everything but the labels.
Please let me know if you're missing any information.
Thanks in advance.
This issue is actually a Highcharts bug. I've reported it here: https://github.com/highcharts/highcharts/issues/10429.
As a workaround, you can use Highcharts.SVGRenderer to add a custom label and store reference to it in your component. Next, when updating, call attr() method on the label (Highcharts.SVGElement) and set new options. Check demo and code posted below.
Add a label on chart callback:
constructor() {
const self = this;
this.chartCallback = chart => {
self.chart = chart;
self.label = chart.renderer
.text("test", 100, 100)
.css({
fill: "#555",
fontSize: 16
})
.add()
.toFront();
};
}
call attr() on the label while updating:
update_chart() {
const self = this,
chart = this.chart;
chart.showLoading();
setTimeout(() => {
chart.hideLoading();
self.chartOptions.series = [
{
data: [10, 25, 15],
name: "updatedSerieName"
}
];
self.chartOptions.yAxis.title.text = "updatedData";
self.label
.attr({
text: "test1",
x: 150,
y: 120
})
.css({
fill: "red",
fontSize: 20
});
self.updateFromInput = true;
}, 2000);
}
Demo:
https://codesandbox.io/s/8zo0yvqqwj
API reference:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#text
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
So i have the following configuration:
const frequencyChartoption = {
title: {},
tooltip: {},
legend: {
data: ['Frekvens', 'Vigtighed']
},
xAxis: {
type: 'category',
data: ['marker_01', 'marker_02'],
axisLabel: {
formatter: function (value) {
return '{' + value + '| }\n{value|}';
},
margin: 20,
rich: {
value: {
lineHeight: 30,
align: 'center'
},
marker_01: {
height: 20,
align: 'center',
backgroundColor: {
image: icons.marker_01
}
},
marker_02: {
height: 20,
align: 'center',
backgroundColor: {
image: icons.maker_02
}
},
}
}
},
yAxis: {},
series: [{
name: 'Frekvens',
type: 'bar',
data: frequencyChartFrequencyScore,
tooltip: icons.marker_01,
itemStyle: {
normal: {
color: colors[0],
label: {
interval: 5,
show: true,
position: 'top',
formatter: '\n{c}'
}
}
}
},
{
name: 'Vigtighed',
type: 'bar',
data: frequencyChartImportance,
itemStyle: {
normal: {
color: colors[1],
label: {
show: true,
position: 'top',
formatter: '\n{c}'
}
}
}
}
]
};
Now as you can see i am using two images as my xAxis
Now i wish to make these show up on my tooltip when i hover over the chart. However i am not quite sure how to do that and was hoping some of you might be able to help?
Simply stated, a series may have a tooltip but the tooltip must be listed as an object with an identifying trigger (see tooltip documentation).
series: [{
name: 'Frekvens',
type: 'bar',
data: frequencyChartFrequencyScore,
tooltip: {
show: true,
trigger: 'axis',
formatter: (params) => {
// see tooltip.formatter for details
// you want to focus on the 'marker' property
return params[0].name;
}
}
}]
With this in mind, you can set two variables and print them as need be within the output of your tooltip. See the additional example below (from CodePen).
var myChart = echarts.init(document.getElementById("main"));
// specify chart configuration item and data
var option = {
title: {
text: "ECharts entry example"
},
tooltip: {
show: true,
trigger: "axis",
backgroundColor: 'rgba(0, 0, 0, 0.8)',
formatter: (params) => {
// create new marker
var icon0 = `<span data-tooltip="minimum" style="border-left: 2px solid #fff;display: inline-block;height: 12px;margin-right: 5px;width: 20px;"><span style="background-color:${params[0].color};display: block;height: 4px;margin-top: 4px;width: 20px;"></span></span>`;
var icon1 = `<span data-tooltip="implied-high" style="background-color:rgba(255,255,255,.75);border-radius: 2px;display: inline-block;height: 12px;margin-right:5px;width: 20px;"><span style="background-color:${params[0].color};border: 1px solid ${params[0].color};border-radius:50%;display:block;height:6px;margin-left:7px;margin-top:3px;width:6px;"></span></span>`;
console.log("params", params, params[0].name);
return `${icon0} ${params[0].name}
${icon1} ${params[0].value}`;
},
textStyle: {
fontWeight: 'bold',
fontSize: 18
}
},
legend: {
data: ["Sales"]
},
xAxis: {
data: ["shirt", "cardign", "chiffon shirt", "pants", "heels", "socks"]
},
yAxis: {},
series: [
{
name: "Sales",
type: "bar",
data: [5, 20, 36, 10, 10, 20]
}
]
};
// use configuration item and data specified to show chart
myChart.setOption(option);
I have created a Bar graph using echarts. I want to bind multiple values to data object dynamically, currently I'm able to bind only single value. here is my java script. I'mm a newbie for this, hoping for a fully functional solution.
var myChart = echarts.init(document.getElementById('page_views_today'));
var option = {
// Setup grid
grid: {
zlevel: 0,
x: 20,
x2: 40,
y: 20,
y2: 20,
borderWidth: 0,
backgroundColor: 'rgba(0,0,0,0)',
borderColor: 'rgba(0,0,0,0)',
},
// Add tooltip
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow', // line|shadow
lineStyle: { color: 'rgba(0,0,0,.5)', width: 1 },
shadowStyle: { color: 'rgba(0,0,0,.1)' }
}
},
// Add legend
legend: {
data: []
},
toolbox: {
orient: 'vertical',
show: true,
showTitle: true,
color: ['#bdbdbd', '#bdbdbd', '#bdbdbd', '#bdbdbd'],
feature: {
mark: { show: false },
dataZoom: {
show: true,
title: {
dataZoom: 'Data Zoom',
dataZoomReset: 'Reset Zoom'
}
},
dataView: { show: false, readOnly: true },
magicType: {
show: true,
itemSize: 12,
itemGap: 12,
title: {
line: 'Line',
bar: 'Bar',
},
type: ['line', 'bar'],
option: {
/*line: {
itemStyle: {
normal: {
color:'rgba(3,1,1,1.0)',
}
},
data: [1,2,3,4,5,6,7,8,9,10,11,12]
}*/
}
},
restore: { show: false },
saveAsImage: { show: true, title: 'Save as Image' }
}
},
// Enable drag recalculate
calculable: true,
// Horizontal axis
xAxis: [{
type: 'category',
boundaryGap: false,
data: [
'0h-2h', '2h-4h', '4h-6h', '6h-8h', '8h-10h', '10h-12h', '12h-14h', '14h-16h', '16h-18h', '18h-20h', '20h-22h', '22h-24h'
],
axisLine: {
show: true,
onZero: true,
lineStyle: {
color: 'rgba(63,81,181,1.0)',
type: 'solid',
width: '2',
shadowColor: 'rgba(0,0,0,0)',
shadowBlur: 5,
shadowOffsetX: 3,
shadowOffsetY: 3,
},
},
axisTick: {
show: false,
},
splitLine: {
show: false,
lineStyle: {
color: '#fff',
type: 'solid',
width: 0,
shadowColor: 'rgba(0,0,0,0)',
},
},
}],
// Vertical axis
yAxis: [{
type: 'value',
splitLine: {
show: false,
lineStyle: {
color: 'fff',
type: 'solid',
width: 0,
shadowColor: 'rgba(0,0,0,0)',
},
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
onZero: true,
lineStyle: {
color: '#ff0000',
type: 'solid',
width: '0',
shadowColor: 'rgba(0,0,0,0)',
shadowBlur: 5,
shadowOffsetX: 3,
shadowOffsetY: 3,
},
},
}],
// Add series
series: [
{
name: 'Page Views',
type: 'bar',
smooth: true,
symbol: 'none',
symbolSize: 2,
showAllSymbol: true,
barWidth: 10,
itemStyle: {
normal: {
color: 'rgba(63,81,181,1.0)',
borderWidth: 2, borderColor: 'rgba(63,81,181,1)',
areaStyle: { color: 'rgba(63,81,181,1)', type: 'default' }
}
},
data: []
}
]
};
Here is my java-script function from where I want to bind the values dynamically.
// Load data into the ECharts instance
load_graph_with_positions(option);
function load_graph_with_positions(option) {
option.series[0].data[0] = 1234;
myChart.setOption(option);
}
One way to do this is by passing values in an array and then shifting the previous values, while pushing-in the data. Following is the example of shiting and pushing the data:
option.series[0].data.shift();
option.series[0].data.push(json.num);
Hence your function will become:
function load_graph_with_positions(option,values) {
var valuesLength = values.length;
for (var i = 0; i < valuesLength; i++) {
option.series[0].data.shift();
option.series[0].data.push(values[i]);
}
myChart.setOption(option);
}
You can also refer to following github example for dynamic addition:
https://github.com/hisune/Echarts-PHP/blob/master/demo/dynamic.php