i'm using bubble chart from Highcharts, the label text inside of the bubbles is dynamic and sometimes can be bigger than the bubble itself,
I wonder if there's a way to make the text ellipsis according to the size of the bubble that contain it?
containerOptions = {
chart: {
type: 'bubble',
renderTo: $(container)[0],
events: {
drilldown: function (e) {
if (!e.seriesOptions) {
var chart = this,
drilldowns = {
'Animals': {
name: 'Animals',
data: [
{name: 'Dogs', y:2, x:10, z: 7, drilldown: true},
{name: 'Cats', y:4, x:12, z: 7}
]
},
'Dogs': {
name:"Dogs",
data: [
{name: 'Pitbull', y:3.7, x:7.6, z: 5, drilldown: false},
{name: 'German shepherd', y:6.7, x:6.9, z: 5, drilldown: false}
]
}
},
series = drilldowns[e.point.name];
chart.showLoading('Loading..');
setTimeout(function () {
chart.hideLoading();
chart.addSeriesAsDrilldown(e.point, series);
}, 1000);
}
}
}
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
style: { color: 'red' },
format: '{point.name}'
}
}
},
series: [{
name: 'Things',
colorByPoint: true,
data: [{
name: 'Animals',
y: 5,
x: 1,
z: 9,
drilldown: true
}, {
name: 'Fruits',
y: 2,
x: 9,
z: 9,
drilldown: false
}
]
}],
drilldown: {
series: [],
drillUpButton: {
relativeTo: 'spacingBox',
position: {
y: 0,
x: 0
}
}
}
}
}
You can loop through the data labels on load/redraw event and add/remove ellipsis according to the bubble's width and text's width.
function applyEllipsis() {
var series = this.series[0];
var options = series.options.dataLabels;
series.points.forEach(p => {
var r = p.marker.radius;
var label = p.dataLabel;
var text = label.text.textStr;
var bbox = label.getBBox(true);
while (bbox.width > 2 * r && text.length !== 1) {
text = text.slice(0, -1);
p.dataLabel.attr({
text: text + '\u2026'
});
bbox = label.getBBox(true);
}
p.dataLabel.align({
width: bbox.width,
height: bbox.height,
align: options.align,
verticalAlign: options.verticalAlign
}, null, p.dlBox);
});
}
Attach the function on load/redraw
Highcharts.chart('container', {
chart: {
type: 'bubble',
events: {
load: applyEllipsis,
redraw: applyEllipsis
}
},
example: http://jsfiddle.net/12d997o4/
Related
I have this part of a slide code, and I want to implement the gsap split Text in h1 (NexText), so that the result is like this: https://codepen.io/GreenSock/pen/aVJRBg
However, I don't know how to implement that in my code.
function nextSlide(pageNumber) {
const nextPage = pages[pageNumber];
const currentPage = pages[current];
const nextLeft = nextPage.querySelector(".hero .model-left");
const nextRight = nextPage.querySelector(".hero .model-right");
const currentLeft = currentPage.querySelector(".hero .model-left");
const currentRight = currentPage.querySelector(".hero .model-right");
const nextText = nextPage.querySelector("h1");
const portofolio = document.querySelector(".portofolio");
const tl = new TimelineMax({
onStart: function() {
slides.forEach(slide => {
slide.style.pointerEvents = "none";
});
},
onComplete: function() {
slides.forEach(slide => {
slide.style.pointerEvents = "all";
});
}
});
tl.fromTo(currentLeft, 0.3, { y: "-10%" }, { y: "-100%" })
.fromTo(currentRight, 0.3, { y: "10%" }, { y: "100%" }, "-=0.2")
.to(portofolio, 0.3, { backgroundImage: backgrounds[pageNumber] })
.fromTo(
currentPage,
0.3,
{ opacity: 1, pointerEvents: "all" },
{ opacity: 0, pointerEvents: "none" }
)
.fromTo(
nextPage,
0.3,
{ opacity: 0, pointerEvents: "none" },
{ opacity: 1, pointerEvents: "all" },
"-=0.6"
)
.fromTo(nextLeft, 0.6, { y: "-100%" }, { y: "-10%" }, "-=0.6")
.fromTo(nextRight, 0.4, { y: "100%" }, { y: "10%" }, "-=0.8")
.fromTo(nextText, 0.3, { opacity: 0, y: 0 }, { opacity: 1, y: 0 })
.set(nextLeft, { clearProps: "all" })
.set(nextRight, { clearProps: "all" });
current = pageNumber;
}
In particular, I don't know how to make these two parts combine:
const nextText = nextPage.querySelector ("h1");
and
var mySplitText = new SplitText ("# quote", {type: "chars, words, lines"})
What you are trying to achieve can be done via:
var variableThatStoresMySplit H1= new SplitText (nextText , {type: "chars"})
And then later in your code you have to use a stagger to through the array SplitText created for you by doing:
gsap.staggerFrom(variableThatStoresMySplit .chars, 0.5, {y:20, opacity:0}, 0.04)
I hope this solves your issue
I am unable to get Link:dbclick event on double click of link with vertexAdding: set to true.
with Vertex Adding set to false the dbclick event works fine.
i am using link:pointerup to add Tool view to link like this::
this.paper.on('link:pointerup', (linkView) => {
var tools;
var ns = joint.linkTools;
var toolsView = new joint.dia.ToolsView({
name: 'link:pointerup',
tools: [
new ns.Vertices(),
new ns.Vertices({ vertexAdding: true}),
new ns.Remove({ focusOpacity: 0.5,
distance: 5,
offset: 10}),
new ns.TargetArrowhead(),
new ns.Segments(),
new ns.Boundary({ padding: 10 }),
]
});
joint.ui.Halo.clear(this.paper);
joint.ui.FreeTransform.clear(this.paper);
this.paper.removeTools();
linkView.addTools(toolsView);
});
For Link Creation:::
export class Link2 extends joint.shapes.standard.Link {
defaults() {
return joint.util.defaultsDeep({
router: {
name: 'normal',
},
connector: {
name: 'normal',
},
labels: [],
attrs: {
line: {
stroke: '#284f96',
strokeDasharray: '0',
strokeWidth: 1,
fill: 'none',
sourceMarker: {
d: 'M 0 0 0 0',
fill: {
type: 'color-palette',
group: 'marker-source',
when: { ne: { 'attrs/line/sourceMarker/d': 'M 0 0 0 0' } },
index: 2
},
},
targetMarker: {
d: ' M 0 -3 -6 0 0 3 z',
},
}
}
}, joint.shapes.standard.Link.prototype.defaults);
}
defaultLabel = {
attrs: {
rect: {
fill: '#ffffff',
stroke: '#8f8f8f',
strokeWidth: 2,
refWidth: 10,
refHeight: 10,
refX: 0,
refY: 0
}
}
};
getMarkerWidth(type: any) {
const d = (type === 'source') ? this.attr('line/sourceMarker/d') : this.attr('line/targetMarker/d');
console.log("marker width", this.getDataWidth(d));
return this.getDataWidth(d);
}
getDataWidth = memoize(function (d: any) {
return (new joint.g.Rect(d)).bbox().width;
});
static connectionPoint(line: any, view: any, magnet: any, opt: any, type: any, linkView: any) {
// const markerWidth = linkView.model.getMarkerWidth(type);
opt = { offset: 5, stroke: true };
// connection point for UML shapes lies on the root group containg all the shapes components
const modelType = view.model.get('type');
if (modelType.indexOf('uml') === 0) opt.selector = 'root';
// taking the border stroke-width into account
if (modelType === 'standard.InscribedImage') opt.selector = 'border';
return joint.connectionPoints.boundary.call(this, line, view, magnet, opt, type, linkView);
}
}
and i am using following code to get double click event on Link:::
this.rappid.paper.on(
"link:pointerdblclick", (linkView) => {
// linkView.model.attr("priority",0);
console.log("linkview", linkView);
// this.currentLink = linkView
this.setState({ modalView: "lableModal", visible: true, currentLink: linkView });
});
I want to convert below chart to SVG so that I can export it to PDF/PPT along with other contents.
click here to see the demo chart
I know I have highchart export, but I can't use it since I have something else apart from chart and html2canvas is not an option because of some security reasons.
function _getDiamondGraphLabel(head, body, lvl, positionLeft, primeColor) {
var positionedTopClass = '',
headFormatted = '',
bodyFormatted = '',
positionedLeftClass = '';
if (lvl) {
positionedTopClass = 'diamond-graph-label-lvl-' + lvl;
}
if (positionLeft) {
positionedLeftClass = 'diamond-graph-label-left';
}
headFormatted = '<div class="diamond-graph-head-label">' + head + '</div>';
bodyFormatted = '<div class="diamond-graph-body-label"><b>' + body + '</b></div>';
var retVal = '<div ' + (primeColor ? 'style="border-color: ' + primeColor + '; border-width: 3px"' : '') + ' class="diamond-graph-label ' +
positionedTopClass + ' ' + positionedLeftClass + '""><div class="diamond-graph-label-content" ' +
(primeColor ? 'style="background-color: ' + primeColor + ' ; color: white"' : '') + '>' + headFormatted + bodyFormatted + '</div></div>';
return retVal;
}
var min = 49560,
per10 = 49560,
per25 = 63560,
per75 = 102537,
per90 = 119537,
median = 83362,
average = 89142,
max = 119537,
counter = 0;
var tickerPositions = [min, per10, per25, per75, per90, median, average, max];
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'columnrange',
inverted: true,
plotBackgroundColor: '#e9e9e9',
height: 25,
plotHeight: 60,
width: $('#container')[0].clientWidth,
spacing: [0, 0, 0, 0]
},
title: {
text: ''
},
xAxis: {
tickLength: 0,
labels: {
enabled: false
}
},
yAxis: {
tickPositions: tickerPositions,
labels: {
useHTML: true,
formatter: function () {
// There is a bug in Highcharts that formatter is calling twice. (reset if the value is higher than tickers length)
if (counter >= tickerPositions.length) {
counter = 0;
}
counter++;
switch (counter) {
case 2:
return _getDiamondGraphLabel('10th', this.value, 0, false, '#000');
case 3:
return _getDiamondGraphLabel('25th', this.value, 1, false, '#000');
case 4:
return _getDiamondGraphLabel('75th', this.value, 1, true, '#000');
case 5:
return _getDiamondGraphLabel('90th', this.value, 0, true, '#000');
case 6:
return _getDiamondGraphLabel("Median", this.value, 2, average < median, "#000");
case 7:
return _getDiamondGraphLabel("Average", this.value, 2, average > median, '#000');
default:
return '<div></div>';
}
}
},
title: {
text: null
}
},
legend: {
enabled: false
},
tooltip: {
enabled: false
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
plotOptions: {
columnrange: {
grouping: false,
borderWidth: 0,
pointPadding: 0,
groupPadding: 0
}
},
series: [{
name: 'MinTo10th',
stack: 'DIAMOND_STACK',
data: [{
x: 0,
low: min,
high: per10
}],
color: '#ebebeb'
}, {
name: '10thTo25th',
stack: 'DIAMOND_STACK',
data: [{
x: 0,
low: per10,
high: per25
}],
color: '#bbbbbb'
}, {
name: '25thTo75th',
stack: 'DIAMOND_STACK',
data: [{
x: 0,
low: per25,
high: per75
}],
color: '#6a6a6a'
}, {
name: '75thTo90th',
stack: 'DIAMOND_STACK',
data: [{
x: 0,
low: per75,
high: per90
}],
color: '#bbbbbb'
}, {
name: '90thToMax',
stack: 'DIAMOND_STACK',
data: [{
x: 0,
low: per90,
high: max
}],
color: '#ebebeb'
}, {
name: 'median',
stack: 'DIAMOND_STACK',
data: [{
x: 0,
low: median,
high: median + 1
}],
color: '#1a8099'
}, {
name: 'average',
stack: 'DIAMOND_STACK',
data: [{
x: 0,
low: average,
high: average + 1
}],
color: '#006699'
}]
});
Can somebody help me with it.
Thanks in advance.
I am using high chart version v4.0.4, i have worked bar chart like mentioned below i need output with there bar for every year details given below
I am working on below high chart code
var data_first_vd = 0;
var data_second_vd = 0;
var glb_data_ary = [];
var dynamicval1 = 5.85572581;
var dynamicval2 = 0.16091656;
if((dynamicval1>1) || (dynamicval2>1)){
var data_tit = 'Value';
var data_val = '${value}';
var prdelvalaxis = 1000000;
}else{
prdelvalaxis = 1000;
data_tit = "Value";
data_val = "${value}";
}
data_first_vd=5.86;
data_second_vd =0.16;
var data_first_ud =1397.128;
var data_second_ud = 28.145;
data_first_ud_lbl = '1.40M';
data_second_ud_lbl = '28K';
data_first_vd_lbl = '5.86M';
data_second_vd_lbl = '161K';
data_first_vd_lbl_xaxis = '$5.86M';
data_second_vd_lbl_xaxis = '$161K';
var ud1 = 1397;
var ud2 = 28;
var vd1 = 6;
var vd2 = 0;
$('#id').highcharts({
credits: { enabled: false },
chart: {
type: 'bar',
height: 200,
marginLeft: 120,
marginBottom:50,
marginTop: 47,
marginRight:30,
plotBorderWidth: 0,
},
title: {
text: null
},
xAxis: {
drawHorizontalBorders: false,
labels: {
groupedOptions: [{
rotation: 270,
}],
rotation: 0,
align:'center',
x: -30,
y: 5,
formatter: function () {
if (curYear === this.value) {
return '<span style="color:#6C9CCC;">' + this.value + '</span>';
}
else if (prevYear === this.value) {
return '<span style="color: #ED7D31;">' + this.value + '</span>';
}
else if ('VALUE' === this.value) {
return '<span style="color:#942EE1;">' + this.value + '</span>';
}
else{
return '<span style="color: #E124D2;">' + this.value + '</span>';
}
},
useHTML:true
},
categories: [{
name: "UNITS",
categories: [2017, 2016]
},{
name: "VALUE",
categories: [2017, 2016]
}
],
},
yAxis: [{ // Primary yAxis
labels: {
format: data_val,
formatter: function () {
if(this.value!=0){
return '$'+valueConverter_crt(this.value*prdelvalaxis);
}else{
return this.value;
}
},
style: {
color: '#942EE1'
}
},
title: {
text: "<span style='font-size: 12px;'>"+data_tit+"</span>",
style: {
color: '#942EE1'
},
useHTML:true
}
}, { // Secondary yAxis
title: {
text: "<span style='font-size: 12px;'>Units</span>",
style: {
color: '#E124D2'
},
useHTML:true
},
labels: {
format: '{value}',
formatter: function () {
if(this.value!=0){
return cal_pro_del_xaxis(this.value);
}else{
return this.value;
}
},
style: {
color: '#E124D2'
}
},
opposite: true
}],
tooltip: { enabled: false },
exporting: { enabled: false },
legend: { enabled: false },
plotOptions: {
series: {
dataLabels: {
inside: true,
align: 'left',
enabled: true,
formatter: function () {
return this.point.name;
},
color: '#000000',
},
stacking: false,
pointWidth: 15,
groupPadding: 0.5
},
},
series: [{
yAxis: 1,
data: [{y:1397.128,name:data_first_ud_lbl,color:'#6C9CCC'},{y:28.145,name:data_second_ud_lbl,color:'#ED7D31'}],
}, {
data: [null,null,{y:5.86,name:data_first_vd_lbl_xaxis,color:'#6C9CCC'},{y:0.16,name:data_second_vd_lbl_xaxis,color:'#ED7D31'}],
}]
});
I need out put like below chart This chart i draw in paint.
Here 3 bar added in every year
Please help me to achieve this
What we are trying to do is to:
display crosshairs only if number of visible series > 1 (color: black)
otherwise disable crosshairs or alternatively set color transparent
Here are our problems:
independent of the number of visible series the crosshairs is not shown for the first hover (but for all subsequent hovers)
our main problem is that the color is not changing although the console.log displays that the color is correctly set due to the number of visible series
Please see the fiddle: example
Thanks for your suggestions!
$(function () {
var chart = new Highcharts.Chart({
chart: {
type: 'area',
renderTo: 'container'
},
title: {
text: 'Historic and Estimated Worldwide Population Growth by Region'
},
subtitle: {
text: 'Source: Wikipedia.org'
},
xAxis: {
categories: ['1750', '1800', '1850', '1900', '1950', '1999', '2050'],
tickmarkPlacement: 'on',
title: {
enabled: false
}
},
yAxis: {
title: {
text: 'Billions'
},
labels: {
formatter: function () {
return this.value / 1000;
}
}
},
tooltip: {
formatter: function () {
// show crosshairs only if visible series >1, else transparent
var nVisible = 0;
for (var i = 0; i < chart.series.length; i++) {
if (chart.series[i].visible) {
nVisible++;
};
if (nVisible > 1) {
break;
};
};
if (nVisible > 1) {
chart.options.tooltip.crosshairs = {
width: 1.5,
dashStyle: 'solid',
color: 'black'
};
} else {
chart.options.tooltip.crosshairs = {
color: 'transparent'
};
};
console.log(chart.options.tooltip.crosshairs.color);
return this.y + ' Billions';
},
backgroundColor: 'rgba(255,255,255,0.95)'
},
plotOptions: {
area: {
stacking: 'normal',
lineColor: '#666666',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#666666'
}
}
},
series: [{
name: 'Asia',
data: [502, 635, 809, 947, 1402, 3634, 5268]
}, {
name: 'Africa',
data: [106, 107, 111, 133, 221, 767, 1766]
}, {
name: 'Europe',
data: [163, 203, 276, 408, 547, 729, 628]
}, {
name: 'America',
data: [18, 31, 54, 156, 339, 818, 1201]
}, {
name: 'Oceania',
data: [2, 2, 2, 6, 13, 30, 46]
}]
});
});
Don't add crosshair in real time, instead when chart is initialized, enable crosshair and then manage color by attr() updating. For example: http://jsfiddle.net/D5DME/3/
Code:
tooltip: {
crosshairs: [{
width: 1.5,
dashStyle: 'solid',
color: 'black'
}, false],
formatter: function () {
// show crosshairs only if visible series >1, else transparent
var nVisible = 0;
for (var i = 0; i < this.series.chart.series.length; i++) {
if (this.series.chart.series[i].visible) {
nVisible++;
};
};
if(this.series.chart.tooltip.crosshairs[0]) {
if (nVisible > 1) {
this.series.chart.tooltip.crosshairs[0].attr({
stroke: 'black'
});
} else {
this.series.chart.tooltip.crosshairs[0].attr({
stroke: 'rgba(0,0,0,0)'
});
}
}
return this.y + ' Billions';
},
backgroundColor: 'rgba(255,255,255,0.95)'
},
It looks to me that the tooltip code is the wrong place to be trying this. I would use the series hide and show event handlers to detect how many series were showing (a simple counter which increments in show and decrements in hide would work).
http://api.highcharts.com/highstock#plotOptions.series.events.hide
You could try the chart setting options depending on the count.
However, I'm not sure that simply settting chart.options.tootlip. will work dynamically the way you want.