I have developed a horizontal Bar chart using Vue-chart.js, all the data and labels are coming from API. The problem is that the value is also visible along with the label, How can I hide the value appearing beside the label? The image is given below
I have the following code.
import { HorizontalBar } from 'vue-chartjs'
export default {
name: 'diagram',
extends: HorizontalBar,
data: () => ({
chartData: '',
score: {},
value: [],
keys: [],
options: {
scales: {
xAxes: [{
ticks: {
scaleShowLabels:false,
}
}],
yAxes: [{
ticks: {
scaleShowLabels:false,
mirror: true
}
}]
},
responsive: true,
},
responsive: true,
maintainAspectRatio: false
}),
created () {
// Overwriting base render method with actual data.
this.$http({
method: 'get',
url: this.base_url + '/exam/api/score/' + this.$store.state.user.id + '/',
auth: {
username: 'my-username',
password: 'my-password'
},
}).then(res => {
console.log(res);
if (res.status == '200') {
console.log(res.data);
this.score = res.data;
for (let v in this.score) {
this.value.push(this.score[v]);
}
for (let key in this.score) {
this.keys.push(key);
}
}
});
this.fillData()
},
mounted(){
this.renderChart(this.chartData, this.options);
},
methods: {
fillData () {
this.chartData = {
labels: this.keys,
datasets: [
{
fillColor: "#ffecbf",
strokeColor: "#dacdd2",
data: this.value,
}
],
}
}
},
watch: {
data: function () {
this._chart.destroy();
this.renderChart(this.chartData, this.options);
},
},
}
please help me out. Thanks in advance.
Related
i have this bar graph made with echar, and i want to add information to the tooltip that it shows when you select a bar in the graph, how can i to do that?
this is the graphic code:
option: {
title: {
text: "Unidades que Necesitan Mantenimiento por Kilometro",
//subtext: "Living Expenses in Shenzhen",
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
data: [],
axisTick: {
alignWithLabel: true,
},
},
],
yAxis: [
{
type: "value",
},
{
type: "value",
},
],
series: [
{
name: "Kilometraje Excedido",
type: "bar",
barWidth: "60%",
data: [],
},
],
},
here i load actually the information from my request, i want to load the information from Año_del_Modelo and Fecha_del_Ultimo_Servis also i want to add a label that says "Modelo", and "Ultimo Servis":
async obtenerUnidadesMantenimientoImportante() {
var respuesta;
this.url =
this.urlBase + "reporte/obtenerunidadesmantenimientoimportante";
const config = {
headers: {
Authorization: `Bearer ${sessionStorage.getItem("Token")}`,
},
};
respuesta = await this.$http
.get(this.url, config)
.then((response) => response.data);
var i = 0;
while (i < 9) {
this.modelos.push(respuesta[i].Año_del_Modelo);
this.ultMantenimientos.push(respuesta[i].Fecha_del_Ultimo_Servis);
this.option.xAxis[0].data.push(respuesta[i].Unidad);
this.option.series[0].data.push(
respuesta[i].Km_Restante_de_Proximo_Servis * -1
);
i++;
}
},
Is there any way to get the visible values on a chart after zooming or panning, using react-chartjs-2? I found a solution without the react version, but I'm not sure how to reference the "chart object" in react. I tried the solution as is, but it doesn't display the visible values, but rather keeps increasing the height of my charts (stretches downwards).
So what would the react solution look like?
Here's my attempt with the linked solution
options:
const chartStyle = {
options: {
animation: false,
maintainAspectRatio: true,
responsive: true,
plugins: {
zoom: {
zoom: {
wheel: {
enabled: true,
modifierKey: "shift",
},
pinch: {
enabled: true,
},
enabled: true,
drag: true,
mode: "x",
onZoomComplete: getVisibleValues,
},
pan: {
enabled: true,
mode: "x",
speed: 2,
onPanComplete: getVisibleValues,
},
mode: "xy",
},
legend: {
display: false,
},
},
scales: {
y: {
type: "linear",
display: "true",
position: "left",
grid: {
drawBorder: true,
color: "#000000",
},
ticks: {
beginAtZero: true,
color: "#000000",
},
},
x: {
max: 9,
grid: {
drawBorder: true,
color: "#00000",
},
ticks: {
beginAtZero: false,
color: "#000000",
},
},
},
},
};
function getVisibleValues({ chart }) {
let x = chart.scales["x-axis-0"];
document.getElementById("vv").innerText = JSON.stringify(
chart.data.datasets[0].data.slice(x.minIndex, x.maxIndex + 1)
);
}
export default chartStyle;
Here's my attempt at accessing the chart instance with useRef(), but ref.scales is undefined:
const SingleChart = ({ chosenDevice, variable }) => {
const [chartData, setChartData] = useState({
labels: [],
datasets: [
{
label: variable,
data: [],
fill: false,
backgroundColor: "rgb(0,0,0)",
borderColor: "rgba(0,0,0, 0.8)",
color: "rgb(0,0,0)",
pointRadius: 4,
yAxisID: "y",
},
],
});
const [apiData, setApiData] = useState({});
const processEnv = process.env;
// USEREF ATTEMPT
const ref = useRef();
console.log(ref.scales);
let x = ref.scales["x"];
console.log("min index", x.minIndex);
console.log("max index", x.maxIndex);
useEffect(() => {
ChartComp.register(zoomPlugin);
var chartDataUrl = processEnv.REACT_APP_CHART_API + chosenDevice;
async function updatePPK() {
if (chosenDevice !== "") {
const dataResponse = await fetch(chartDataUrl);
var dataBody = await dataResponse.json();
for (var key in dataBody) {
dataBody[key].PV_POWER =
dataBody[key].PV_CURR * dataBody[key].PV_CURR;
}
setApiData(dataBody);
}
}
updatePPK();
}, [chosenDevice]);
useEffect(() => {
var chartLabels = [];
var chartValues = [];
console.log(apiData);
console.log("keys", Object.keys(apiData) !== 0);
if (Object.keys(apiData).length !== 0) {
for (var key in apiData) {
if (variable == "GEN_ON") {
chartValues.push(apiData[key][variable] == "ON" ? 1 : 0);
} else {
chartValues.push(apiData[key][variable]); // for every element in the passed in chartData object from hookMqtt, add the variable the graph requests (this.variable) to an array of data to be displayed
}
chartLabels.push(apiData[key]["TIME_COMMITED"].substring(11, 19));
}
setChartData({
labels: chartLabels,
datasets: [
{
label: variable,
data: chartValues,
fill: false,
backgroundColor: "rgb(0,0,0)",
borderColor: "rgba(0,0,0, 0.8)",
color: "rgb(0,0,0)",
pointRadius: 4,
yAxisID: "y",
},
],
});
console.log(chartData);
}
}, [chosenDevice, apiData]);
return (
<div>
<Line
ref={ref}
data={chartData}
options={variable != "GEN_ON" ? chartStyles.options : genStyle.options}
width={20}
height={10}
/>
</div>
);
};
SingleChart.propTypes = {
chartData: PropTypes.any,
chosenDevice: PropTypes.any,
setDate: PropTypes.any,
variable: PropTypes.any,
state: PropTypes.any,
};
export default SingleChart;
I've added a condition in componentDidMount to showcase data for either 1 or 2 datasets based on the pros recieved. However, I'm getting an error in the if condition. Here is BarChart component. Inside it, I've already imported Chart from 'chart.js'.
class BarChart1 extends Component {
constructor(props) {
super(props);
}
chartRef = React.createRef();
componentDidMount() {
const myChartRef = this.chartRef.current.getContext("2d");
let dataCheck = null;
if(this.props.data2){
let dataCheck = {
labels: this.props.labels,
datasets: [
{
label: this.props.label1,
backgroundColor: 'rgba(26,179,148,0.5)',
borderColor: "rgba(26,179,148,0.7)",
data: this.props.data1
}, {
label: this.props.label2,
backgroundColor: 'rgba(220, 220, 220, 0.5)',
pointBorderColor: "#fff",
data: this.props.data2
}
]
}
}
else {
let dataCheck = {
labels: this.props.labels,
datasets: [
{
label: this.props.label1,
backgroundColor: 'rgba(26,179,148,0.5)',
borderColor: "rgba(26,179,148,0.7)",
data: this.props.data1
}
]
}
}
new Chart(myChartRef, {
type: 'bar',
data: {dataCheck},
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
display: true,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
},
gridLines: {
display: false
}
}],
xAxes: [{
gridlines: {
display: false
},
ticks: {
fontSize: 9
}
}]
}
},
plugins: [{
beforeInit: function(chart) {
chart.data.labels.forEach(function(e, i, a) {
if (/\n/.test(e)) {
a[i] = e.split(/\n/);
}
});
}
}]
})
}
render() {
return <canvas ref={this.chartRef} />
}
}
I've edited my question. I'm now getting a blank chart without the error.
There are two errors in your code.
Your have to end the variable declaration with ; instead of ,
You have to declare datacheck outside the if else block unless you want it undefined
componentDidMount() {
...
let dataCheck;
if(this.props.data2){
dataCheck = {
...
}
}
else {
dataCheck = {
...
}
}
}
How can I bind pie chart and line chart together rather than appear one by one? And the pie charts which appear later than line chart will block the line chart. Is there any chance the pie and line can appear together in the end?
The current situation is that
at the beginning,and then.
This is the JS code.
var dom2 = document.getElementById('demo');
var chart = echarts.init(dom2);
var option = {
title: {
text: '中药与疾病'
},
tooltip: {},
legend: {
data: ['中药', '疾病']
},
xAxis: {
data: []
},
yAxis: [
{},
{}
],
series: [
{
name: '中药',
type: 'line',
data: [],
yAxisIndex: 0
},
{
name: '疾病',
type: 'line',
data: [],
yAxisIndex: 1
}
]
}
chart.setOption(option);
$.get('https://gist.githubusercontent.com/Linya-gzl/4d4f388e1b0e3d8e05c38f875b94a97c/raw/8c121acbfaf4aac9eccaf6b81cd1b3614203c185/demo1.json').done(function (data) {
dataArr = JSON.parse(data);
console.log(dataArr);
chart.setOption({
xAxis: {
data: dataArr.map(row => row['categories'])
},
series: [{
name: '中药',
data: dataArr.map(row => row['value1'])
},
{
name: '疾病',
data: dataArr.map(row => row['value2'])
}]
});
function buildPieSeries() {
var len = dataArr.length;
for (var i = 0; i < len; i++) {
option.series.push({
type: 'pie',
radius: 15,
center: [110 + 90 * i, dataArr[i].value2 - 100],
label: {
show: true,
textStyle: {
fontSize: 8
}
},
data: [
{ value: dataArr[i].value1, name: '黄连' },
{ value: dataArr[i].value2, name: '黄芩' },
]
})
}
chart.setOption(option, true);
}
setTimeout(buildPieSeries, 1000);
});
and
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.7.0/echarts.min.js" integrity="sha256-eKrx6Ly6b0Rscx/PSm52rJsvK76RJyv18Toswq+OLSs=" crossorigin="anonymous"></script>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<div id="demo" style="width: 600px;height:400px;"></div>
I changed your code a bit in the series insertion part, by my opinion need inserting series completely because partial inserts sometimes cause problems with merging data. Also I fixed coordinate calculation, more correct way take the already calculated coordinates from line if they the same.
document.addEventListener("DOMContentLoaded", e => {
var targetNode = document.querySelector('#chartNode');
var chartInstance = echarts.init(targetNode);
var option = {
title: { text: '中药与疾病' },
tooltip: {},
legend: { data: ['中药', '疾病'] },
xAxis: { data: [] },
yAxis: [
{},
{}
],
series: [
{
name: '中药',
type: 'line',
data: [],
yAxisIndex: 0
},
{
name: '疾病',
type: 'line',
data: [],
yAxisIndex: 1
}
]
}
chartInstance.setOption(option);
$.get('https://gist.githubusercontent.com/Linya-gzl/4d4f388e1b0e3d8e05c38f875b94a97c/raw/8c121acbfaf4aac9eccaf6b81cd1b3614203c185/demo1.json').done(function (data) {
dataArr = JSON.parse(data);
chartInstance.setOption({
xAxis: {
data: dataArr.map(row => row['categories'])
},
series: [{
name: '中药',
data: dataArr.map(row => row['value1'])
},
{
name: '疾病',
data: dataArr.map(row => row['value2'])
}]});
pieSeries = chartInstance.getOption().series;
function buildPieSeries() {
var len = dataArr.length;
for (var i = 0; i < len; i++) {
pieSeries.push({
type: 'pie',
radius: 15,
z: 10,
center: chartInstance.getModel().getSeriesByName('中药')[0].getData().getItemLayout(i),
// center: [110 + 90 * i, dataArr[i].value2 - 100],
label: {
show: true,
textStyle: {
fontSize: 8
}},
data: [
{ value: dataArr[i].value1, name: '黄连' },
{ value: dataArr[i].value2, name: '黄芩' },
]
})
};
chartInstance.setOption({ series: pieSeries });
}
setTimeout(() => buildPieSeries(), 1000);
});
});
<script src="https://cdn.jsdelivr.net/npm/echarts#4.7.0/dist/echarts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="chartNode" style="width: 600px;height:400px;"></div>
I want to show 10 data in a pie chart, but only show 2 of them.
my version is v2.8.0
chart.getDatasetMeta(i).hidden=true;
this is work in bar charts, but not work in pie.
var donutOptions = {...}
var donutChartCanvas = $(pieChart).get(0).getContext(2d);
var donutData = {
labels: [],
texts: [],
datasets: [
{
data: [ ],
backgroundColor : []
}
]
};
var donutChart = new Chart(donutChartCanvas, {
plugins: [ChartDataLabels],
type: doughnut,
data: donutData,
options: donutOptions
});
getDatasetMeta undefined.
now is:
I want to this:
I find a work way, try it.
add
legend : {
}
into option
var donutOptions = {
maintainAspectRatio : false,
responsive : true,
animation: {
animateScale: true,
animateRotate: true
},
tooltips: {
intersect: false,
callbacks: {
label: function (tooltipItem, data) {
...
}
},
},
plugins: {
datalabels: {
...
},
},
},
legend : {
}
};
and use this
donutChart.chart.getDatasetMeta(0).data[index].hidden = true;
donutChart.update();