I created a custom legend panel for an Ext chart using Ext.draw.Text.... In my application, legends may have long custom texts. So I need to split them using a fixed length. One way would be two split the text using Javascript and create text sprites for each part of text.
Is there any other way to split text in Ext.draw.Text?
Code:
Ext.create('Ext.draw.Component', {
renderTo: Ext.getBody(),
width: 800,
height: 200,
items: [{
type: 'rect',
fill: 'red',
width: 12,
height: 12,
x: 5,
y: 10
},{
type: "text",
text: "This is a long text.. Can i split this into two tspan",
fill: "green",
width: 12,
height: 12,
font: "18px monospace",
x: 25,
y: 15
}]
});
Thanks In Advance.
I was successfully able to generate multiple tspan for Ext.draw.text by inserting new line characters in text content('\n'). JSFiddle
Ext.create('Ext.draw.Component', {
renderTo: Ext.getBody(),
width: 800,
height: 200,
items: [{
type: 'rect',
fill: 'red',
width: 12,
height: 12,
x: 5,
y: 10
},{
type: "text",
text: "This is a long text.. \n Can i split this into two tspan", //Added new line character
fill: "green",
width: 12,
height: 12,
font: "18px monospace",
x: 25,
y: 15
}]
});
Related
I'm trying to pin a pie chart to the left.
A negative marginLeft and center: ['20%', '50%'] don't give me what i need
since when changing the screen width the position of the chart also changes.
I am using Vue 3 composition api
series: [{
center: ['20%', '90%'],
size: '150%',
innerSize: '65%',
data: [
{
name: 'Valid',
y: 10,
color: '#13CE66'
},
{
name: 'Failed Verification',
y: 5,
color: '#FF4949'
}
],
showInLegend: true
}]
It should be like this:
Use the chart.marginLeft property
Example config:
chart: {
type: 'pie',
width: 400,
height: 200,
marginLeft: -230
},
Example demo:
https://jsfiddle.net/BlackLabel/k52j7m9x/
API Reference:
https://api.highcharts.com/highcharts/chart.marginLeft
I want to create a single bar using a bar chart. The setup is that the user can select different choices (representing the colors). In this example (codesandbox link below) I have a bar that has a max value of 90.000. The three chosen values are 20.000, 30.000 and 15.000, totaling 65.000.
Now, my goal is to have a border around this entire bar, not just the colors. In the image below this is represented with the red border. Currently I do this by putting a container element around my canvas element, but I would like to do this in the canvas itself, without using a container element. Someone has an idea on how to do this?
Codesandbox link
You need to define different dataset properties such as borderSkipped, borderRadius, borderWidth to achieve what you're looking for.
Don't know why but I also had to define the data of the dataset at the bottom as a floating bar in order to see the rounded border.
data: [[0, 20000]]
Please take a look at the runnable code below and see how it could work.
new Chart('chart', {
type: 'bar',
data: {
labels: [''],
datasets: [{
label: "currentAmount",
data: [[0, 20000]],
backgroundColor: "#bbb",
borderColor: "#f00",
borderWidth: 2,
borderSkipped: 'top',
borderRadius: 30,
barPercentage: 0.5
},
{
label: "amount 1",
data: [30000],
backgroundColor: "orange",
borderColor: "#f00",
borderWidth: { left: 2, right: 2 },
barPercentage: 0.5
},
{
label: "amount 2",
data: [15000],
backgroundColor: "green",
borderColor: "#f00",
borderWidth: { left: 2, right: 2 },
barPercentage: 0.5
},
{
label: "remaining",
data: [25000],
backgroundColor: "#fff",
borderColor: "#f00",
borderWidth: 2,
borderSkipped: 'bottom',
borderRadius: 30,
barPercentage: 0.5
},
]
},
options: {
plugins: {
legend: {
display: false
},
tooltip: {
displayColors: false
}
},
scales: {
y: {
display: false,
stacked: true,
beginsAtZero: true
},
x: {
display: false,
stacked: true
}
}
}
});
canvas {
max-width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<canvas id="chart"></canvas>
Does anyone has clue how to target specific grid line and style like in the example?
I know how to dash line with:
grid: {
strokeDashArray: 10,
},
But how can I target grid line according to the tick value?
Desired result
Only way you can do it is via css
.apexcharts-gridline:nth-child(2) {
stroke-dasharray: 10;
}
Or use annotations instead https://apexcharts.com/docs/annotations/
I have sorted it by using annotations property. Here is an example:
// Breakdown line
annotations: {
position: 'front',
yaxis: [
{
y: 3000,
strokeDashArray: 5,
label: {
position: 'left',
borderColor: 'transparent',
textAnchor: 'middle',
offsetY: -10,
offsetX: 50,
style: {
color: '#D0D4D9',
background: "transparent",
},
text: ''
}
}
]
}
I am using highcharts and a phantomjs server to render charts and labels but the useHTML flag while rendering the labels does not seem to be working. I started the server as mentioned in the docs
phantomjs highcharts-convert.js -host 127.0.0.1 -port 3003
and then I am sending post requests with the following as the infile
{
chart: {
events: {
load: function() {
var label = this.renderer.label('Hello World', useHTML=true)
.css({
color: '#FF11FF',
fontSize: '12px'
})
.attr({
fill: 'rgba(0, 0, 100, 0.75)',
padding: 8,
r: 5,
zIndex: 6
})
.add()
box = label.getBBox();
label.align(Highcharts.extend(box, {
align: 'center',
verticalAlign: 'top',
x: 0,
y: 20
}),
null, 'spacingBox');
var label2 = this.renderer.label('Goodbye World')
.css({
color: '#222222'
})
.add()
label2.align(Highcharts.extend(label2.getBBox(), {
align: 'left',
verticalAlign: 'top',
x: 0,
y: box.height + 40
}),
null, 'spacingBox');
}
},
height: 800,
width: 500
},
title: {
text: ''
}
};
I am then exporting this as an svg, but the text for the label gets printed as it is. I also tried
var label = this.renderer.label('Hello World',null, null, 'rect', null, null, true)
but this leads to the first text not being displayed at all, the blue background gets added and so does the second text but not the first text. The first one is not even working on export.highcharts.com but the second one works fine over there. What am I doing wrong here ?
Renderer.label takes more arguments than you provided, docs:
http://api.highcharts.com/highcharts/Renderer.label
Example:
this.renderer.label('Hello World',null,null,null,null,null,true)
Your fiddle with proper use of Renderer.label:
https://jsfiddle.net/6atnc2xj/
I'm trying to increment text value everytime I click on the rectangle. What am I doing wrong ?
I don't understand because the call to my var works in drawText but doesn't in setLayer.
I looked at "setLayer" source code, who's working with '+=' syntax, but text is a String var and I don't want to make String concatenation.
value=1
$('canvas').drawText({
name: 'count',
fillStyle: '#0f0',
x: 20, y: 20,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: value
})
.drawRect({
strokeStyle: '#000',
fillStyle: '#ccc',
x: 20, y: 50,
width: 20,
height: 20,
layer: true,
click: function(layer) {
// Spin
$(this).animateLayer(layer, {
rotate: '+=180'
});
v=parseInt(value);
$(this).setLayer('count',{
text: value+1 // TRYING to increment over here
});
}})
Removing and recreating layers will make jCanvas unhappy. A much better solution would be to use setLayer() by parsing the current value to a number, incrementing that value, and passing it to the method:
$('canvas').drawText({
layer: true,
name: 'count',
fillStyle: '#0f0',
x: 20, y: 20,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: '1'
})
.drawRect({
strokeStyle: '#000',
fillStyle: '#ccc',
x: 20, y: 50,
width: 20,
height: 20,
layer: true,
click: function(layer) {
var $canvas = $(this),
countLayer = $canvas.getLayer('count');
// Spin
$canvas.animateLayer(layer, {
rotate: '+=180'
});
$canvas.setLayer(countLayer,{
text: parseFloat(countLayer.text) + 1
});
}
});
I found a workaround removing the layer and creating a new one at the same place.
function updateCount(param) {
$('canvas').removeLayer("count")
.drawText({
name: 'count',
fillStyle: '#0f0',
x: 250, y: 180,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: value,
layer: true,
maxWidth: 200
})
.drawLayers();
}