Rickshaw CSS/Axes in JSDOM - node.js

I'm using Node on a server side application, to dynamically produce graphs. I'm using d3.js and rickshaw.js to create SVG versions of the graph, and imagemagick to convert that SVG into a png. I am using JSDOM as my DOM.
I am getting this error: https://github.com/shutterstock/rickshaw/issues/186
The solution given here is to pull in the css, I found an answer on stack overflow on how to do this with JSDOM:
How do you ad stylesheets to JSDOM
So I've followed these instructions, and pulled in a rickshaw.css. When I print the DOM to console, I can see it in the head, in a style element.
var mainCss = fs.readFileSync(path.normalize("rickshaw.css"), 'utf8');
console.log("mainCss",mainCss);
var document = jsdom.jsdom("<!DOCTYPE html><html><meta http-equiv=\"content-type\"content=\"text/html; charset=utf-8\"><head></head><body id=\"abody\"><div id=\"chart_container\"><div id=\"y_axis\"></div><div id=\"chart\"></div></div></body></html>", jsdom.level(3, 'index'), {
features : {
FetchExternalResources : ['script', 'css'],
QuerySelector : true
}
});
GLOBAL.window = document.parentWindow;
var head = document.getElementsByTagName('head')[0];
style = document.createElement("style");
style.type = 'text/css';
style.innerHTML = mainCss;
head.appendChild(style);
I'm setting up my graph as so:
var graph = new Rickshaw.Graph( {
element: document.querySelector('#chart'),
width: 600,
height: 600,
series: seriesArr
});
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph
});
var xAxis = new Rickshaw.Graph.Axis.Time({
graph: graph,
timeUnit: "hour"
});
yAxis.render();
xAxis.render();
graph.render();
utils.convertSVGtoPNG(document.querySelector('#chart').innerHTML);
Still I am getting a black square, as my output SVG.
Am I missing something? Am I thinking about something wrong? Any help would be greatly appreciated.

Unfortunately, it looks like imagemagick doesn't support external CSS and other people asking for solutions for similar problems haven't received any alternative suggestions for tools that do. So you're going to have to make sure that the relevant styles are applied inline in order for your SVG to PNG converter to recognize them.
The universal way to do this would be to write a script that traverses the CSS-DOM, grabs each rule, selects all elements that match the rule, and applies the corresponding styles to them as inline styles.
However, that would probably be overkill for your needs. Your specific problem is caused by the default style for <path> elements, which is solid black fill and no stroke. When using grid lines, this means that the axis domain path gets drawn as a solid black rectangle covering the entire plotting area.
The simple solution is therefore to select these paths after drawing the axes, and apply custom styles directly:
d3.selectAll("path.domain")
.style({ fill:"none",
stroke:"black",
stroke-width:1,
});

If anyone is interested in the d3 selectors to replicate all css, as recommended by Amelia here they are:
d3.selectAll("path.domain")
.style({ "fill":"none",
"stroke":"black",
"stroke-width":1
});
d3.selectAll("path.domain")
.style({
"fill": "none",
"stroke": "black",
"stroke-width": "1"
});
d3.selectAll(".rickshaw_graph .detail")
.style({
"pointer-events": "none",
"position": "absolute",
"top": "0",
"z-index": "2",
"background": "rgba(0, 0, 0, 0.1)",
"bottom": "0",
"width": "1px",
"transition": "opacity 0.25s linear",
"-moz-transition": "opacity 0.25s linear",
"-o-transition": "opacity 0.25s linear",
"-webkit-transition": "opacity 0.25s linear"
});
d3.selectAll(".rickshaw_graph .detail.inactive ")
.style({
"opacity": "0"
});
d3.selectAll(".rickshaw_graph .detail .item.active ")
.style({
"opacity": "1"
});
d3.selectAll(".rickshaw_graph .detail .x_label ")
.style({
"font-family": "Arial, sans-serif",
"border-radius": "3px",
"padding": "6px",
"opacity": "0.5",
"border": "1px solid #e0e0e0",
"font-size": "12px",
"position": "absolute",
"background": "white",
"white-space": "nowrap"
});
d3.selectAll(".rickshaw_graph .detail .x_label.left ")
.style({
"left": "0"
});
d3.selectAll(".rickshaw_graph .detail .x_label.right ")
.style({
"right": "0"
});
d3.selectAll(".rickshaw_graph .detail .item ")
.style({
"position": "absolute",
"z-index": "2",
"border-radius": "3px",
"padding": "0.25em",
"font-size": "12px",
"font-family": "Arial, sans-serif",
"opacity": "0",
"background": "rgba(0, 0, 0, 0.4)",
"color": "white",
"border": "1px solid rgba(0, 0, 0, 0.4)",
"margin-left": "1em",
"margin-right": "1em",
"margin-top": "-1em",
"white-space": "nowrap"
});
d3.selectAll(".rickshaw_graph .detail .item.left ")
.style({
"left": "0"
});
d3.selectAll(".rickshaw_graph .detail .item.right ")
.style({
"right": "0"
});
d3.selectAll(".rickshaw_graph .detail .item.active ")
.style({
"opacity": "1",
"background": "rgba(0, 0, 0, 0.8)"
});
d3.selectAll(".rickshaw_graph .detail .dot ")
.style({
"width": "4px",
"height": "4px",
"margin-left": "-2px",
"margin-top": "-2px",
"border-radius": "5px",
"position": "absolute",
"box-shadow": "0 0 2px rgba(0, 0, 0, 0.6)",
"background": "white",
"border-width": "2px",
"border-style": "solid",
"display": "none",
"background-clip": "padding-box"
});
d3.selectAll(".rickshaw_graph .detail .dot.active ")
.style({
"display": "block"
});
/* graph */
d3.selectAll(".rickshaw_graph ")
.style({
"position": "relative"
});
d3.selectAll(".rickshaw_graph svg ")
.style({
"display": "block",
"overflow": "hidden"
});
d3.selectAll(".rickshaw_graph .x_tick ")
.style({
"position": "absolute",
"top": "0",
"bottom": "0",
"width": "0px",
"border-left": "1px dotted rgba(0, 0, 0, 0.2)",
"pointer-events": "none"
});
d3.selectAll(".rickshaw_graph .x_tick .title ")
.style({
"position": "absolute",
"font-size": "12px",
"font-family": "Arial, sans-serif",
"opacity": "0.5",
"white-space": "nowrap",
"margin-left": "3px",
"bottom": "1px"
});
d3.selectAll(".rickshaw_annotation_timeline ")
.style({
"height": "1px",
"border-top": "1px solid #e0e0e0",
"margin-top": "10px",
"position": "relative"
});
d3.selectAll(".rickshaw_annotation_timeline .annotation ")
.style({
"position": "absolute",
"height": "6px",
"width": "6px",
"margin-left": "-2px",
"top": "-3px",
"border-radius": "5px",
"background-color": "rgba(0, 0, 0, 0.25)"
});
d3.selectAll(".rickshaw_graph .annotation_line ")
.style({
"position": "absolute",
"top": "0",
"bottom": "-6px",
"width": "0px",
"border-left": "2px solid rgba(0, 0, 0, 0.3)",
"display": "none"
});
d3.selectAll(".rickshaw_graph .annotation_line.active ")
.style({
"display": "block"
});
d3.selectAll(".rickshaw_graph .annotation_range ")
.style({
"background": "rgba(0, 0, 0, 0.1)",
"display": "none",
"position": "absolute",
"top": "0",
"bottom": "-6px"
});
d3.selectAll(".rickshaw_graph .annotation_range.active ")
.style({
"display": "block"
});
d3.selectAll(".rickshaw_graph .annotation_range.active.offscreen ")
.style({
"display": "none"
});
d3.selectAll(".rickshaw_annotation_timeline .annotation .content ")
.style({
"background": "white",
"color": "black",
"opacity": "0.9",
"padding": "5px 5px",
"box-shadow": "0 0 2px rgba(0, 0, 0, 0.8)",
"border-radius": "3px",
"position": "relative",
"z-index": "20",
"font-size": "12px",
"top": "18px",
"left": "-11px",
"width": "160px",
"display": "none",
"cursor": "pointer"
});
d3.selectAll(".rickshaw_annotation_timeline .annotation.active .content ")
.style({
"display": "block"
});
d3.selectAll(".rickshaw_annotation_timeline .annotation:hover .content ")
.style({
"display": "block",
"z-index": "50"
});
d3.selectAll(".rickshaw_graph .y_axis, .rickshaw_graph .x_axis_d3 ")
.style({
"fill": "none"
});
d3.selectAll(".rickshaw_graph .y_ticks .tick, .rickshaw_graph .x_ticks_d3 .tick ")
.style({
"stroke": "rgba(0, 0, 0, 0.16)",
"stroke-width": "2px",
"shape-rendering": "crisp-edges",
"pointer-events": "none"
});
d3.selectAll(".rickshaw_graph .y_grid .tick, .rickshaw_graph .x_grid_d3 .tick ")
.style({
"z-index": "-1",
"stroke": "rgba(0, 0, 0, 0.20)",
"stroke-width": "1px",
"stroke-dasharray": "1 1"
});
d3.selectAll(".rickshaw_graph .y_grid .tick[data-y-value=\"0\"] ")
.style({
"stroke-dasharray": "1 0"
});
d3.selectAll(".rickshaw_graph .y_grid path,.rickshaw_graph .x_grid_d3 path ")
.style({
"fill": "none",
"stroke": "none"
});
d3.selectAll(".rickshaw_graph .y_ticks path, .rickshaw_graph .x_ticks_d3 path ")
.style({
"fill": "none",
"stroke": "#808080"
});
d3.selectAll(".rickshaw_graph .y_ticks text, .rickshaw_graph .x_ticks_d3 text ")
.style({
"opacity": "0.5",
"font-size": "12px",
"pointer-events": "none"
});
d3.selectAll(".rickshaw_graph .x_tick.glow .title, .rickshaw_graph .y_ticks.glow text ")
.style({
"fill": "black",
"color": "black",
"text-shadow":
"-1px 1px 0 rgba(255, 255, 255, 0.1),1px -1px 0 rgba(255, 255, 255, 0.1),1px 1px 0 rgba(255, 255, 255, 0.1),0px 1px 0 rgba(255, 255, 255, 0.1),0px -1px 0 rgba(255, 255, 255, 0.1),1px 0px 0 rgba(255, 255, 255, 0.1),-1px 0px 0 rgba(255, 255, 255, 0.1),-1px -1px 0 rgba(255, 255, 255, 0.1)"
});
d3.selectAll(".rickshaw_graph .x_tick.inverse .title, .rickshaw_graph .y_ticks.inverse text")
.style({
"fill": "white",
"color": "white",
"text-shadow": "-1px 1px 0 rgba(0, 0, 0, 0.8),1px -1px 0 rgba(0, 0, 0, 0.8),1px 1px 0 rgba(0, 0, 0, 0.8),0px 1px 0 rgba(0, 0, 0, 0.8),0px -1px 0 rgba(0, 0, 0, 0.8),1px 0px 0 rgba(0, 0, 0, 0.8),-1px 0px 0 rgba(0, 0, 0, 0.8),-1px -1px 0 rgba(0, 0, 0, 0.8)"
});
d3.selectAll(".rickshaw_legend ")
.style({
"font-family": "Arial",
"font-size": "12px",
"color": "white",
"background": "#404040",
"display": "inline-block",
"padding": "12px 5px",
"border-radius": "2px",
"position": "relative"
});
d3.selectAll(".rickshaw_legend .swatch ")
.style({
"width": "10px",
"height": "10px",
"border": "1px solid rgba(0, 0, 0, 0.2)"
});
d3.selectAll(".rickshaw_legend .line ")
.style({
"clear": "both",
"line-height": "140%",
"padding-right": "15px"
});
d3.selectAll(".rickshaw_legend .line .swatch ")
.style({
"display": "inline-block",
"margin-right": "3px",
"border-radius": "2px"
});
d3.selectAll(".rickshaw_legend .label ")
.style({
"margin": "0",
"white-space": "nowrap",
"display": "inline",
"font-size": "inherit",
"background-color": "transparent",
"color": "inherit",
"font-weight": "normal",
"line-height": "normal",
"padding": "0px",
"text-shadow": "none"
});
d3.selectAll(".rickshaw_legend .action ")
.style({
"margin-right": "0.2em",
"font-size": "10px",
"opacity": "0.2",
"cursor": "pointer"
});
d3.selectAll(".rickshaw_legend .line.disabled ")
.style({
"opacity": "0.4"
});
d3.selectAll(".rickshaw_legend ul ")
.style({
"list-style-type": "none",
"margin": "0",
"padding": "0",
"cursor": "pointer"
});
d3.selectAll(".rickshaw_legend li ")
.style({
"padding": "0 0 0 2px",
"min-width": "80px",
"white-space": "nowrap"
});
It isn't formatted well, and I've had to remove any class that had pseudo-selectors.

Related

Nested child elements not displaying in JSON column formatting in Microsoft List in SharePoint Online

I am trying to create a Status column which displays the progress of a multi stage approval flow.
This JSFiddle demonstrates how it should look:
I am now converting the HTML and CSS into the JSON required for column formatting.
All the conditional logic and colors are working, however it is not outputting the nested child elements.
The nested child elements (spans) are the 'arrows' at the end of each stage.
The column formatting therefore looks like this:
The associated HTML in browser developer tools console looks like this:
(you can see that the nested spans are not being output at all)
At first, I was wondering if nested children were allowed in JSON column formatting.
But I have seen other examples where people are using it (example), so that doesn't seem to be the issue.
Below is the JSON column formatting I am using.
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json",
"elmType": "div",
"style":
{
"font-size": "16px"
},
"children":
[
{
"elmType": "div",
"txtContent": "Stage 01",
"style":
{
"float": "left",
"padding": "10px 30px 10px 40px",
"position": "relative",
"font-family": "Arial",
"background-color": "=if([$Stage1Person] == '', '#eee', '#aeffae')"
},
"children":
[
{
"elmType": "span",
"style":
{
"position": "absolute",
"top": "0",
"right": "-19px",
"width": "0",
"height": "0",
"border-top": "21px solid transparent",
"border-bottom": "20px solid transparent",
"z-index": "2",
"background-color": "=if([$Stage1Person] == '', '#eee', '#aeffae')"
}
}
]
},
{
"elmType": "div",
"txtContent": "Stage 02",
"style":
{
"float": "left",
"padding": "10px 30px 10px 40px",
"position": "relative",
"font-family": "Arial",
"background-color": "=if([$Stage2Person] == '', '#ffdcae', '#aeffae')"
},
"children":
[
{
"elmType": "span",
"style":
{
"position": "absolute",
"top": "0",
"right": "-19px",
"width": "0",
"height": "0",
"border-top": "21px solid transparent",
"border-bottom": "20px solid transparent",
"z-index": "2",
"background-color": "=if([$Stage2Person] == '', '#ffdcae', '#aeffae')"
}
}
]
},
{
"elmType": "div",
"txtContent": "Stage 03",
"style":
{
"float": "left",
"padding": "10px 30px 10px 40px",
"position": "relative",
"font-family": "Arial",
"background-color": "=if([$Stage3Person] == '', '#ffaeae', '#aeffae')"
},
"children":
[
{
"elmType": "span",
"style":
{
"position": "absolute",
"top": "0",
"right": "-19px",
"width": "0",
"height": "0",
"border-top": "21px solid transparent",
"border-bottom": "20px solid transparent",
"z-index": "2",
"background-color": "=if([$Stage3Person] == '', '#ffaeae', '#aeffae')"
}
}
]
}
]
}
Simplified JSON
Here is a more simplified version which also demonstrates how the nested CHILD elements are not being output as HTML:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json",
"elmType": "div",
"style":
{
"font-size": "16px"
},
"children":
[
{
"elmType": "div",
"txtContent": "Stage 01",
"style":
{
"float": "left",
"padding": "10px 30px 10px 40px",
"position": "relative",
"font-family": "Arial",
"background-color": "=if([$Stage1Person] == '', '#eee', '#aeffae')"
},
"children":
[
{
"elmType": "span",
"txtContent": "Stage 01 - CHILD"
}
]
},
{
"elmType": "div",
"txtContent": "Stage 02",
"style":
{
"float": "left",
"padding": "10px 30px 10px 40px",
"position": "relative",
"font-family": "Arial",
"background-color": "=if([$Stage2Person] == '', '#ffdcae', '#aeffae')"
},
"children":
[
{
"elmType": "span",
"txtContent": "Stage 02 - CHILD"
}
]
},
{
"elmType": "div",
"txtContent": "Stage 03",
"style":
{
"float": "left",
"padding": "10px 30px 10px 40px",
"position": "relative",
"font-family": "Arial",
"background-color": "=if([$Stage3Person] == '', '#ffaeae', '#aeffae')"
},
"children":
[
{
"elmType": "span",
"txtContent": "Stage 03 - CHILD"
}
]
}
]
}

Thumbnail View on Sharepoint 2016 Document Library

is it possible to change view from list to thumbnail on document library sharepoint 2016?
I've searched for documentation on google, youtube, microsoft still can't find the answer, please help. Currently the display of the user is still a list
You could achieve this by using view formatting.
Make sure your library contains 'Type', 'Create by' and 'Type' column.
1.View -> formatting current view -> Prase following code.
enter image description here
2.Choose layout to 'Gallery'-> save.
code template:
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json Jump ",
"tileProps": {
"hideSelection": true,
"height": "280",
"width": "300",
"formatter": {
"elmType": "div",
"style": {
"align-items": "stretch",
"margin": "3px 2px",
"background-color": "#fbfbfb",
"height": "380px",
"overflow": "inherit",
"border-radius": "2px",
"box-shadow": "0px 1.6px 3.6px 0 #00000024, 0px 0.3px 0.9px 0 #00000024"
},
"children": [
{
"elmType": "div",
"style": {
"display": "flex",
"flex-wrap": "wrap",
"position": "relative",
"padding-bottom": "10px",
"width": "100%"
},
"children": [
{
"elmType": "div",
"style": {
"margin-top": "0px",
"height": "200px",
"display": "block",
"align-items": "center",
"justify-content": "center",
"position": "relative",
"border-bottom": "1px solid #EEE",
"overflow": "hidden",
"border-radius": "2px 2px 0 0"
},
"children": [
{
"elmType": "button",
"style": {
"position": "absolute",
"height": "100%",
"width": "100%",
"opacity": "0",
"cursor": "pointer"
},
"customRowAction": {
"action": "defaultClick"
}
},
{
"elmType": "div",
"style": {
"width": "=if([$File_x0020_Type] == '', '100px', '100%')",
"height": "=if([$File_x0020_Type] == '', '100px', '100%')",
"oveflow": "=if([$File_x0020_Type] == '', 'auto', 'hidden')",
"text-align": "center",
"overflow": "hidden"
},
"children": [
{
"elmType": "img",
"style": {
"height": "=if([$File_x0020_Type] == '', '100%', '0'"
},
"attributes": {
"src": "=if([$File_x0020_Type] == '', 'https://spoprod-a.akamaihd.net/files/fabric/office-ui-fabric-react-assets/foldericons-fluent/folder-large_frontplate_nopreview.svg Jump ', '')"
}
},
{
"elmType": "img",
"style": {
"display": "=if([$File_x0020_Type] == '', 'none', '')"
},
"attributes": {
"src": "#thumbnail.383x383"
}
}
]
}
]
},
{
"elmType": "div",
"style": {
"margin": "25px 0 0 0",
"position": "absolute",
"top": "153px",
"width": "100%",
"color": "#333333"
},
"attributes": {
"class": "ms-fontSize-14 ms-fontWeight-semibold"
},
"children": [
{
"elmType": "img",
"attributes": {
"src": "=if([$File_x0020_Type] == 'docx', 'https://spoprod-a.akamaihd.net/files/fabric/assets/item-types-fluent/20/docx.svg?v6 Jump ', if([$File_x0020_Type] == 'xlsx', 'https://spoprod-a.akamaihd.net/files/fabric/assets/item-types-fluent/20/xlsx.svg?v6 Jump ', if([$File_x0020_Type] == 'pptx', 'https://spoprod-a.akamaihd.net/files/fabric/assets/item-types-fluent/20/pptx.svg?v6 Jump ', if([$File_x0020_Type] == 'pdf', 'https://spoprod-a.akamaihd.net/files/fabric/assets/item-types-fluent/20/pdf.svg?v6 Jump ', if([$File_x0020_Type] == 'jpg' || [$File_x0020_Type] == 'png' || [$File_x0020_Type] == 'gif','https://spoprod-a.akamaihd.net/files/fabric/assets/item-types-fluent/20/photo.svg?v6 Jump ', if([$File_x0020_Type] == 'mp4' || [$File_x0020_Type] == 'avi' || [$File_x0020_Type] == 'mov', 'https://spoprod-a.akamaihd.net/files/fabric/assets/item-types-fluent/20/video.svg?v6 Jump ', if([$File_x0020_Type] == 'zip', 'https://spoprod-a.akamaihd.net/files/fabric/assets/item-types-fluent/20/zip.svg?v6 Jump ','Unknown')))))))"
},
"style": {
"flex": "none",
"line-height": "100%",
"font-weight": "normal",
"font-size": "2rem",
"margin": "5px 5px 5px 10px",
"height": "25px"
}
},
{
"elmType": "div",
"txtContent": "[$FileLeafRef]",
"style": {
"padding": "0 0 0 16px"
}
},
{
"elmType": "div",
"txtContent": "='edited by ' + [$Editor.title]",
"style": {
"padding": "0 0 0 16px"
}
}
]
}
]
}
]
}
}
}

ZingChart Labels disappeared when updating script to 2.5.2

I updated our instance of the ZingChart script to version 2.5.2 today and doing so caused labels to disappear from a chart where they previously showed. I'm not sure if it's an issue with my JSON that just managed not to throw any errors in the previous version of ZingChart or if it's a bug with the current release.
Before:
After:
My JSON:
var maxYValue = 60;
var value1 = 40;
var value2 = 15;
var value3 = 34;
var value4 = 14;
var value5 = 20;
var zones_1 = {
"type": "mixed",
"font-family": "proxima_nova_rgregular",
"title": {
"text": "MINUTES <b>IN ZONES</b>",
"font-family": "proxima_nova_rgregular",
"background-color": "none",
"font-color": "#39393d",
"font-size": "22px",
"adjustLayout": true,
"padding-bottom": 50
},
"plot": {
"borderRadius": "5px 5px 0 0",
"bar-width": '50%',
"animation": {
"delay": 300,
"effect": 11,
"speed": "500",
"method": "0",
"sequence": "3",
"z-index": 2
},
"value-box": {
"placement": "top-out",
"text": "%v",
"decimals": 0,
"font-color": "#35353b",
"font-size": "14px",
"alpha": 1,
"backgroundColor": "#ffffff",
"padding": "5px 5px 0px 5px",
"shadow": false
}
},
"plotarea": {
"border-left": "3px solid #39393d",
"border-bottom": "3px solid #39393d",
"padding-left": "3px",
"margin": "dynamic",
"background-color": "none"
},
"tooltip": {
"visible": false
},
"scale-x": {
"placement": "opposite",
"line-width": 0,
"tick": {
"visible": false
},
"guide": {
"visible": false
},
"item": {
"visible": false
},
},
"scale-y": {
"offsetEnd": 45,
"max-value": maxYValue,
"visible": false,
"line-width": 0,
"guide": {
"visible": false
}
},
"series": [
{
"type": "bar",
"values": [
value1, value2, value3, value4, value5
],
"background-color": "#cdcccc",
"z-index": 2,
"styles": ['#cdcccc', '#71cbdc', '#8cc541', '#d96c27', '#ea2629']
},
{
"type": "line",
"line-color": "grey",
"marker": { "visible": 0 },
"value-box": { visible: 0 },
"values": [
[0, value1 + 2],
[0, maxYValue],
[0, null],
[1, value2 + 2],
[1, maxYValue],
[1, null],
[2, value3 + 2],
[2, maxYValue],
[2, null],
[3, value4 + 2],
[3, maxYValue],
[3, null],
[4, value5 + 2],
[4, maxYValue],
[4, null],
]
}
],
"labels": [
{
"text": "Zone 1",
"font-size": "13px",
"padding": "10px 5px",
"borderWidth": 1,
"borderColor": "#ffffff",
"backgroundColor": "#ffffff",
"callout": true,
"calloutWidth": 0,
"calloutHeight": 5,
'hook': 'scale:name=scale-x,index=0',
'offset-y': -200,
"calloutTip": {
'offset-y': -200,
"type": "circle",
"background-color": "#fff",
"border-width": 2,
"border-color": "#35353b",
"size": 7,
"shadow": false
}
},
{
"text": "Zone 2",
"font-size": "13px",
"padding": "10px 5px",
"borderWidth": 1,
"borderColor": "#ffffff",
"backgroundColor": "#ffffff",
"callout": true,
"calloutWidth": 0,
"calloutHeight": 5,
'hook': 'scale:name=scale-x,index=1',
'offset-y': -200,
"calloutTip": {
'offset-y': -200,
"type": "circle",
"background-color": "#fff",
"border-width": 2,
"border-color": "#35353b",
"size": 7,
"shadow": false
}
},
{
"text": "Zone 3",
"font-size": "13px",
"padding": "10px 5px",
"borderWidth": 1,
"borderColor": "#ffffff",
"backgroundColor": "#ffffff",
"callout": true,
"calloutWidth": 0,
"calloutHeight": 5,
'hook': 'scale:name=scale-x,index=2',
'offset-y': -200,
"calloutTip": {
'offset-y': -200,
"type": "circle",
"background-color": "#fff",
"border-width": 2,
"border-color": "#35353b",
"size": 7,
"shadow": false
}
},
{
"text": "Zone 4",
"font-size": "13px",
"padding": "10px 5px",
"borderWidth": 1,
"borderColor": "#ffffff",
"backgroundColor": "#ffffff",
"callout": true,
"calloutWidth": 0,
"calloutHeight": 5,
'hook': 'scale:name=scale-x,index=3',
'offset-y': -200,
"calloutTip": {
'offset-y': -200,
"type": "circle",
"background-color": "#fff",
"border-width": 2,
"border-color": "#35353b",
"size": 7,
"shadow": false
}
},
{
"text": "Zone 5",
"font-size": "13px",
"padding": "10px 5px",
"borderWidth": 1,
"borderColor": "#ffffff",
"backgroundColor": "#ffffff",
"callout": true,
"calloutWidth": 0,
"calloutHeight": 5,
'hook': 'scale:name=scale-x,index=4',
'offset-y': -200,
"calloutTip": {
'offset-y': -200,
"type": "circle",
"background-color": "#fff",
"border-width": 2,
"border-color": "#35353b",
"size": 7,
"shadow": false
}
}
],
}
Any help would be greatly appreciated. I would prefer to keep the most updated version of the script but really need those labels back.
I can't speak to exactly what the cause of your issue is between builds at the moment but our team will look into it. I did however look at your JSON and I think you can get the output you are looking for in an easier way. I have included an updated chart config below which does work on the newest build.
Full disclosure on the ZingChart team.
var maxYValue = 60;
var value1 = 40;
var value2 = 15;
var value3 = 34;
var value4 = 14;
var value5 = 20;
var myConfig ={
"type": "mixed",
"font-family": "proxima_nova_rgregular",
"title": {
"text": "MINUTES <b>IN ZONES</b>",
"font-family": "proxima_nova_rgregular",
"background-color": "none",
"font-color": "#39393d",
"font-size": "22px",
"adjustLayout": true,
"padding-bottom": 50
},
"plot": {
"borderRadius": "5px 5px 0 0",
"bar-width": '50%',
"animation": {
"delay": 300,
"effect": 11,
"speed": "500",
"method": "0",
"sequence": "3",
"z-index": 2
},
"value-box": {
"placement": "top-out",
"text": "%v",
"decimals": 0,
"font-color": "#35353b",
"font-size": "14px",
"alpha": 1,
"backgroundColor": "#ffffff",
"padding": "5px 5px 0px 5px",
"shadow": false
}
},
"plotarea": {
"border-left": "3px solid #39393d",
"border-bottom": "3px solid #39393d",
"padding-left": "3px",
"margin": "dynamic",
"background-color": "none"
},
"tooltip": {
"visible": false
},
"scale-x": {
"placement": "opposite",
"labels":["Zone 1","Zone 2","Zone 3","Zone 4","Zone 5"],//set zone label here. Much easier than labals:[]
"line-width": 0,
"tick": {
"visible": false
},
"guide": {
"visible": false
},
"item": {
"offsetY": 25,
"font-size": 12,
"fontColor": 'black',
"bold": true
},
},
"scale-y": {
"offsetEnd": 45,
"max-value": maxYValue,
"visible": false,
"line-width": 0,
"guide": {
"visible": false
}
},
"series": [
{
"type": "bar",
"values": [
value1, value2, value3, value4, value5
],
"background-color": "#cdcccc",
"z-index": 2,
"styles": ['#cdcccc', '#71cbdc', '#8cc541', '#d96c27', '#ea2629']
},
{
"type": "line",
"line-color": "gray",
"marker": {
"backgroundColor":"white",
"borderWidth": 3,
"borderColor":"gray",
"visible": false,
"rules":[//create marker which is always at the top of line
{
'rule':" %node-index%3 == 1 ",
visible: true,
size: 10
}
]
},
"value-box": {
visible: 0
},
"values": [
[0, value1 + 2],
[0, maxYValue],
[0, null],
[1, value2 + 2],
[1, maxYValue],
[1, null],
[2, value3 + 2],
[2, maxYValue],
[2, null],
[3, value4 + 2],
[3, maxYValue],
[3, null],
[4, value5 + 2],
[4, maxYValue],
[4, null],
]
}
]
};
zingchart.render({
id: 'myChart',
data: myConfig,
height: '100%',
width: '100%'
});
html, body {
height:100%;
width:100%;
margin:0;
padding:0;
}
#myChart {
height:100%;
width:100%;
min-height:150px;
}
.zc-ref {
display:none;
}
<!DOCTYPE html>
<html>
<head>
<script src= "https://cdn.zingchart.com/zingchart.min.js"></script>
<!--Inject End-->
</head>
<body>
<div id="myChart"><a class="zc-ref" href="https://www.zingchart.com">Powered by ZingChart</a></div>
</body>
</html>
The issue is the offset-y attribute set for the labels & the callout tip. It needs to be removed or set to zero. The new lib code is correct because scale-x has "placement": "opposite" so it is placed above (if you remove visible:false from items you will see).
Most likely the old code was not using the correct y position of the scale thats why you had to use offset-y to correct it.

character width calculation wrong with some font which can make auto indent

i create a normal textbox and type some "i"s inside,the font i use is Lobster1.3,as you can see,i just selection one character,but the result is not correctly
and this is the last character position while in selection.
it looks that some font like Lobster1.3 which can make auto indent can make some character width calculation wrong
You have to ensure the font is properly loaded on the canvas before creating a fabricObject that uses it, if not fabricjs creates a cache of characters width that you have to manually delete to get the good one.
var jsondata = {
"objects": [{
"type": "textbox",
"originX": "left",
"originY": "top",
"left": 50,
"top": 50,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 0,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.7870722433460076,
"scaleY": 1.7870722433460076,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"skewX": 0,
"skewY": 0,
"stretchMode": "any",
"lockScalingX": false,
"lockUniScaling": false,
"lockScalingY": true,
"text": "iiiiiiiii",
"fontSize": "42",
"fontWeight": "normal",
"fontFamily": "Lobster",
"fontStyle": "",
"textDecoration": "",
"textAlign": "left",
"letterSpacing": 20,
"lineHeight": 1.16,
"textBackgroundColor": "",
"charSpacing": 20,
"styles": {
"0": {
"0": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"1": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"2": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"3": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"4": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"5": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"6": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"7": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"8": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
}
}
},
"minWidth": 20,
"lastCachedStyleObject": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
}
}],
"backgroundData": "#ffffff",
"width": 1023,
"height": 637
}
var canvas = new fabric.Canvas("myCanvas");
canvas.controlsAboveOverlay = true;
canvas.backgroundColor = '#FFFFFF';
WebFont.load({
google: {
families: ['Lobster']
},
active: function() {
canvas.loadFromJSON(jsondata, canvas.renderAll.bind(canvas));
}
});
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.16/webfont.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<canvas id='myCanvas' width='800' height='600'></canvas>
Fabric has a method that clears the font cache to ensure you don't get the wrong measurements for your bounding box when loading in and applying fonts to textbox objects.
clearFabricFontCache(fontFamilyopt)
From their documentation
http://fabricjs.com/docs/fabric.util.html
Clear char widths cache for the given font family or all the cache if no fontFamily is specified. Use it if you know you are loading fonts in a lazy way and you are not waiting for custom fonts to load properly when adding text objects to the canvas. If a text object is added when its own font is not loaded yet, you will get wrong measurement and so wrong bounding boxes. After the font cache is cleared, either change the textObject text content or call initDimensions() to trigger a recalculation
So in this case you could write:
canvas.loadFromJSON(jsonData, () => {
//clear character cache to ensure bounding boxes for fonts are correct
fabric.util.clearFabricFontCache();
canvas.renderAll()
});

Adding options in "group" type object in fabricjs canvas

I am trying to load object (group of objects) in canvas, there is no problem with that. But if I want to add some options to loaded object such as scaleX, scaleY, lockScalingX etc. with set method I get an error "Uncaught TypeError: Object Group has no method 'set'". I cannot understand why, I have tried several ways. My code is below -
var json = {
"objects": [{
"type": "group",
"originX": "center",
"originY": "center",
"left": 268,
"top": 203,
"width": 428,
"height": 274,
"fill": "rgb(0,0,0)",
"overlayFill": null,
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"selectable": true,
"hasControls": true,
"hasBorders": true,
"hasRotatingPoint": true,
"transparentCorners": true,
"perPixelTargetFind": false,
"shadow": null,
"visible": true,
"objects": [{
"type": "rect",
"originX": "center",
"originY": "center",
"left": 11,
"top": 37,
"width": 200,
"height": 200,
"fill": "rgba(179,179,179,0.5)",
"overlayFill": null,
"stroke": "#FF0000",
"strokeWidth": 0.1,
"strokeDashArray": null,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"selectable": true,
"hasControls": false,
"hasBorders": true,
"hasRotatingPoint": true,
"transparentCorners": true,
"perPixelTargetFind": false,
"shadow": null,
"visible": true,
"rx": 0,
"ry": 0
}, {
"type": "triangle",
"originX": "center",
"originY": "center",
"left": 114,
"top": -37,
"width": 200,
"height": 200,
"fill": "rgba(179,179,179,0.5)",
"overlayFill": null,
"stroke": "#FF0000",
"strokeWidth": 0.1,
"strokeDashArray": null,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"selectable": true,
"hasControls": false,
"hasBorders": true,
"hasRotatingPoint": true,
"transparentCorners": true,
"perPixelTargetFind": false,
"shadow": null,
"visible": true
}, {
"type": "circle",
"originX": "center",
"originY": "center",
"left": -114,
"top": 29,
"width": 200,
"height": 200,
"fill": "rgba(179,179,179,0.5)",
"overlayFill": null,
"stroke": "#FF0000",
"strokeWidth": 0.1,
"strokeDashArray": null,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"selectable": true,
"hasControls": false,
"hasBorders": true,
"hasRotatingPoint": true,
"transparentCorners": true,
"perPixelTarge,,tFind": false,
"shadow": null,
"visible": true,
"radius": 100
}]
}],
"background": ""
},
objects = json.objects,
canvas = new fabric.Canvas('canvas');
for (var i = 0; i < objects.length; i++) {
var type = fabric.util.string.camelize(fabric.util.string.capitalize(objects[i].type));
type.set({
scaleX: 1.2,
scaleY: 1.2,
lockScalingX: true,
lockScalingY: true
});
type.setCoords();
if (fabric[type].async) {
fabric[type].fromObject(objects[i], function (img) {
canvas.add(img);
});
} else {
canvas.add(fabric[type].fromObject(objects[i]));
}
}
Anyone can help me please?
This exception happens cause the var "type" gets string value which is "Group"
var type = fabric.util.string.camelize(fabric.util.string.capitalize(objects[i].type));
so there is no "set" method in "Group" string as you used:
.set({
scaleX: 1.2,
scaleY: 1.2,})//this is wrong
you can use this :
objects[i].scaleX = 1.2;
objects[i].scaleY = 1.2;
objects[i].lockScalingX = 1.2;
objects[i].lockScalingY = 1.2;
and here the JSfiddle

Resources