I am using GoJS and I want to color the circle inside my node based on certain condition. if the status is "will retire" then color of the circle will be red, if the status is "millenial" then color of the circle will be green, otherwise it will be white. I've made it looked like this
var colors = {
black: "#000000",
white: "#ffffff",
red: "#ff0000",
green: "#00cc00"
}
var fill1 = null;
if (status == "milenial") {
fill1 = colors["green"];
} else if (status == "akan pensiun") {
fill1 = colors["red"];
} else {
fill1 = colors["white"];
}
and in the diagram, by using go.shapes it looked like this
$(go.Shape, "Circle", {
row: 0,
column: 1,
rowSpan: 4,
margin: 3,
fill: fill1,
stroke: colors["white"],
strokeWidth: 1,
width: 25,
height: 25
},
new go.Binding("fill", "color")
I got the status value in the condition by using ajax.
In my code, the shape color fill will stay white/null (I don't really understand which one), while the stroke works fine. I've tried to console.log(fill1), and it showed the colors[] value. But I don't get it why the shape color won't change in the shape.
Please, can anyone explain why this happens and how to get the output I want? I am new and would appreciate any of your help. Thank you
The problem here is that although you are setting the fill when the node is created fill: fill1 the underlying model will not be update when you later update fill1 as its is set to the objects value rather than a reference to the object.
In this case the solution is to use a Binding to create a property you can update in a transaction, for example
GO(go.Shape, "Trapezoid1",
{
name: "SHAPE",
angle: 270,
strokeWidth: 2,
fill: "pink",
minSize: new go.Size(50, 50),
},
new go.Binding("fill", "status", function(type) {
switch (type) {
case "milenial":
return "#00cc00";
case "will retire":
return "#ff0000";
default:
return "#ffffff";
}})
);
Here we are binding "fill" to "status" and using a function to embed your logic into the node.
Elsewhere in you code (where you are using ajax) update the status
function update(key, status) {
// all model changes should happen in a transaction
myDiagram.model.commit(function(m) {
console.log("Finding Node " + key)
var data = m.findNodeDataForKey(key);
m.set(data, "status", status);
}, "update " + status + " for " + key);
};
update("RASP1","will retire" );
update("RASP2","milenial" );
In this example two of my nodes are identified as RASP1 and RASP1 and I'm setting the status to "will retire" and "milenial" respectively. The other two nodes are pink as this is the default colour
Related
I'm trying to create a capital letter "A" as an SVG shape for use with Matter.js but the letter shape displays incorrectly.
CodePen here and duplicated here:
function percentX(percent) {
return Math.round((percent / 100) * window.innerWidth);
}
function percentY(percent) {
return Math.round((percent / 100) * window.innerHeight);
}
const Engine = Matter.Engine,
Bodies = Matter.Bodies,
Body = Matter.Body,
Svg = Matter.Svg,
Vertices = Matter.Vertices,
Composite = Matter.Composite,
Render = Matter.Render,
Runner = Matter.Runner;
// create an engine
const engine = Engine.create(),
world = engine.world;
// create a renderer
const render = Render.create({
element: document.body,
engine: engine,
options: {
wireframes: false,
showInternalEdges: false,
width: percentX(100),
height: percentY(100),
background: "transparent"
}
});
let bodies = [],
bgColor = "#0A0618";
// SVGs
let vertexSets = [],
svgLetter,
svgLetterLegOne,
svgLetterLegTwo,
svgLetterCounter;
let letterX = percentX(60);
let letterY = percentY(20);
let letterXLegOne = percentX(60) - 40;
let letterYLegOne = percentY(20) + 40;
let letterXLegTwo = percentX(60) + 40;
let letterYLegTwo = percentY(20) + 40;
let letterSize = (window.innerWidth / 1000);
// A
// silhouette test (incorrectly displaying Batman ears)
$('#svg-test').find('path').each(function(i, path) {
svgTest = Bodies.fromVertices(
percentX(30),
letterY,
Vertices.scale(Svg.pathToVertices(path, 10),
letterSize,
letterSize), {
render: {
fillStyle: "white",
strokeStyle: "white",
lineWidth: 2
}
}, true);
vertexSets.push(svgTest);
});
// letter base shape
$('#svg-3').find('path').each(function(i, path) {
svgLetter = Bodies.fromVertices(
letterX,
letterY,
Vertices.scale(Svg.pathToVertices(path, 10),
letterSize,
letterSize), {
render: {
fillStyle: "yellow",
strokeStyle: "yellow",
lineWidth: 2
}
}, true);
vertexSets.push(svgLetter);
});
// left leg
$('#svg-3-leg-1').find('path').each(function(i, path) {
svgLetterLegOne = Bodies.fromVertices(
letterXLegOne,
letterYLegOne,
Vertices.scale(Svg.pathToVertices(path, 10),
letterSize,
letterSize), {
render: {
fillStyle: "green",
strokeStyle: "green",
lineWidth: 2,
isStatic: true
}
}, true);
vertexSets.push(svgLetterLegOne);
});
// right leg
$('#svg-3-leg-2').find('path').each(function(i, path) {
svgLetterLegTwo = Bodies.fromVertices(
letterXLegTwo,
letterYLegTwo,
Vertices.scale(Svg.pathToVertices(path, 10),
letterSize,
letterSize), {
render: {
fillStyle: "blue",
strokeStyle: "blue",
lineWidth: 2,
isStatic: true
}
}, true);
vertexSets.push(svgLetterLegTwo);
});
// counter (hole in the center), no need for offset repositioning
$('#svg-3-counter').find('path').each(function(i, path) {
svgLetterCounter = Bodies.fromVertices(
letterX,
letterY,
Vertices.scale(Svg.pathToVertices(path, 10),
letterSize,
letterSize), {
render: {
fillStyle: bgColor,
strokeStyle: bgColor,
lineWidth: 2
}
}, true);
vertexSets.push(svgLetterCounter);
});
// create compound body for letter "A"
var compoundBodyA = Body.create({
parts: [svgLetter, svgLetterLegOne, svgLetterLegTwo, svgLetterCounter]
});
// add A and O compound bodies to the world
Composite.add(world, [
compoundBodyA
]);
// add all SVGs to the world
Composite.add(world, vertexSets);
// run the renderer
Render.run(render);
// create runner
const runner = Runner.create();
// run the engine
Runner.run(runner, engine);
// hold in place for testing
world.gravity.y = 0;
world.gravity.x = 0;
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
*:focus, *::before:focus, *::after:focus {
outline: none;
}
* {
font-family: monaco, courier;
}
body {
margin: 0;
padding: 0;
background: #0A0618;
}
svg {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pathseg#1.2.1/pathseg.js"></script>
<script src="https://cdn.jsdelivr.net/npm/poly-decomp#0.3.0/build/decomp.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
<svg class="svg-letter" id="svg-test">
<path class="st0" d="M59.3,0h46.4l59,141h-50.8l-7.4-18.8h-49L50.3,141h-50L59.3,0z"/>
</svg>
<svg class="svg-letter" id="svg-3">
<path d="M57.2,122.2H7.9L59,0h46.4l51.1,122.2h-50.3H57.2z"/>
</svg>
<svg class="svg-letter" id="svg-3-leg-1">
<path d="M0,141l7.9-18.8h49.3L50,141H0z"/>
</svg>
<svg class="svg-letter" id="svg-3-leg-2">
<path d="M106.2,122.2h50.3l7.9,18.8h-50.8L106.2,122.2z"/>
</svg>
<svg class="svg-letter" id="svg-3-counter">
<path d="M94.6,89L81.8,55L69,89H94.6z"/>
</svg>
I know Matter.js can't always handle SVGs with compound paths (an internal path creating a knockout) so my plan was to have two separate paths, the silhouette of the shape and the knockout, and group them as a compound body. Only the silhouette isn't even displaying correctly (the white version on the left). For some reason, the shape always has those Batman ears which I can't get rid of.
So my new plan is to break the silhouette shape into three parts, the main body (in yellow) and two legs (green and blue). That allows all three parts to have only four sides which seems to prevent the bug.
My problem is positioning those two legs so that they are always precisely butting up against the main body shape. I can adjust the position offset to accomplish this but since I've set the width and height of the render object to be proportional to the width and height of the browser, the letter breaks apart if the page is loaded in any other sized window.
Using variables (lines 45–54), I've tried setting the width and height of the legs to reference the main body shape with offsets:
svgThree.position.x - 40,
svgThree.position.y + 40,
And I've tried keeping all units and offsets proportional:
percentX(60) - percentX(2),
percentY(20) + percentX(2),
But nothing works. Without setting the letter to exact pixel dimensions, is there any way to keep these three paths touching and in precise relation to each other across different browser sizes?
Alternatively, if there's any way to build that SVG shape to avoid that bug, I'd greatly appreciate such a solution.
(Using Chrome Version 102.0.5005.115)
It's not a perfect solution but the one I eventually went with was this:
Setting the letter size to a static number (0.8), instead of a derivation of the window width, allowed me to set the width and height of the two legs of the letter to a static offset distance from the main body shape, so the change in the original CodePen above would be to lines 48–54:
let letterXLegOne = letterX - 43;
let letterYLegOne = letterY + 49;
let letterXLegTwo = letterX + 43;
let letterYLegTwo = letterY + 49;
let letterSize = 0.8;
The fix is incorporated into this CodePen as a final product.
I need to show the label values inside the Highcharts bar chart. It can be implemented using dataLabels.Formatter function.
But when the bar is in consist-able size the labels are shown inside the bar and it is looking good. In some cases, the bar is very small in size comparing to the label.
Please see the code pen here, https://codepen.io/JGSpark/pen/YzzBydv?editors=1010
The last bar is very small and 40 is showing outside. As the color: 'white' is commonly used for all the labels it is showing in white though it is in outside.
How can I change the color of the label if it is showing out?
In this example, I need to change the color of label 40 to black. Any suggestions?
You need to add custom formatter which will check the size of yAxis value and will change the color of label accordingly:
formatter: function() {
var max = this.series.yAxis.max,
color = this.y / max < 0.05 ? 'black' : 'white'; // 5% width
return '<p style="color: ' + color + '">' + this.y + ' M</p>';
},
If your chart is not a dynamically created you can set the dataLabels.color for the particular point.
{
y: 40,
dataLabels: {
color: 'black'
}
}
Demo
API
EDIT
Another solution which I can suggest is to add a functionality inside the chart.events.load which will filter if dataLabels is aligned to left or right and set wanted color - it will work if more labels will be outside the column bar.
events: {
load() {
let chart = this,
series = chart.series;
series[0].points.forEach(p => {
if (p.dataLabel.alignOptions.align === 'left') {
p.dataLabel.css({
color: 'black'
})
}
})
}
}
Demo
API
I'd like to set my own defined colors for graphs that appear in Kintone.
I've found out for pie charts, you can upload the below CSS code to the App to have some areas of the pie to become a color of your choice.
.highcharts-series-group .highcharts-series path:nth-of-type(even){
fill:pink;
}
What I'd really like to do though, is apply the same thing to the Line charts in kintone.
I've tried the below CSS:
.highcharts-tracker path {
fill: red;
}
This only changes the points plotted on the graph, but not the lines in between the points.
How can I identify the lines in this graph so that I can end up with lines of the color of my choice??
Updated 6/24/18
Like you mentioned, the code that I showed you displays only on the record detail page. However, if you just make the process to run on the record list event "app.record.index.show", you can show the graph on the top of the record list page.
Also, it will be better to use kintone.app.getHeaderSpaceElement() to append a graph on the record list page.
The following page is an example of how to append something on the record list page using the kintone.app.getHeaderSpaceElement():
kintone developer network - kintone x OpenStreetMap
https://developer.kintone.io/hc/en-us/articles/115003669514
The following page is about the record list header element:
kintone developer network - Get Record List Header Element
https://developer.kintone.io/hc/en-us/articles/213148937-Get-Record-List#getHeaderSpaceElement
=================================================
Original Reply
It's better off not editing the DOM because it might not work after any kintone updates. I recommend creating a custom graph using Chart.js, a javscript library. The following page helps you how to do so.
Example Code
(function() {
"use strict";
// Events for adding and editing records
var eventsCreateShow = ['app.record.create.show', 'app.record.edit.show',
'app.record.index.create.show', 'app.record.index.edit.show'];
kintone.events.on(eventsCreateShow, function(event) {
// Hide the "Chart" Group field
kintone.app.record.setFieldShown('Chart', false);
});
// Display the chart on the record details page (PC and mobile)
var eventsDetailShow = ['app.record.detail.show', 'mobile.app.record.detail.show'];
kintone.events.on(eventsDetailShow, function(event) {
var record = event.record;
var data = {
labels: ["Language Arts", "Math", "Science", "Social Studies", "P.E."],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(0,140,232,.4)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
data: [
record['language_arts']['value'],
record['math']['value'],
record['science']['value'],
record['social_studies']['value'],
record['pe']['value']
]
}
]
};
// Set Chart.js options
var options = {
scaleShowLine: true,
angleShowLineOut: true,
scaleShowLabels: true,
scaleBeginAtZero: true,
angleLineColor: "rgba(0,0,0,.1)",
angleLineWidth: 1,
pointLabelFontFamily: "'Arial'",
pointLabelFontStyle: "normal",
pointLabelFontSize: 16,
pointLabelFontColor: "#666",
pointDot: true,
pointDotRadius: 5,
pointDotStrokeWidth: 1,
pointHitDetectionRadius: 20,
datasetStroke: true,
datasetStrokeWidth: 3,
datasetFill: true,
responsive: true
};
var elRadar;
var elCanvas = document.createElement('canvas');
elCanvas.id = 'canvas';
// Display radar chart onto the Blank space
// Edit display size depending on PC or mobile
if (event.type === 'mobile.app.record.detail.show') {
elRadar = kintone.mobile.app.getHeaderSpaceElement();
elCanvas.style.position = 'relative';
elCanvas.style.top = '10px';
elCanvas.style.left = '10px';
elCanvas.height = '300';
elCanvas.width = '300';
} else {
elRadar = kintone.app.record.getSpaceElement('Radar');
elCanvas.height = '400';
elCanvas.width = '400';
}
elRadar.appendChild(elCanvas);
var myChart = new Chart(elCanvas.getContext("2d")).Radar(data, options);
});
})();
Ref:kintone developer network - Display radar charts with chart.js
https://developer.kintone.io/hc/en-us/articles/115006413388-Display-radar-charts-with-chart-js
I hope this helps
I have created a line graph using highchart js .I want to set a grey color marker at the starting and a red colored mrker at the end of my graph.Is there a way to do it with highcharts?
In the load event (chart.events.load) you can extract first and last point from series. Then call update() function to modify fillColor parameter.
chart:{
events:{
load:function() {
var chart = this,
series = chart.series[0],
data = series.data,
len = data.length;
//first point
data[0].update({
marker:{
fillColor: 'gray'
}
},false);
//last point
data[len - 1].update({
marker:{
fillColor: 'red'
}
});
}
}
},
Example:
http://jsfiddle.net/s9erv8f0/
when I merge boundary colours of 2 Map Levels (Department and Arrondissment) , the mouse hover done wrong for 2nd Layer (Arrondissment)
My Bug on Arrondissment Layer is like this
Hovering should be done like
For merging the Border color , I Applied the following logic on Arrondissment Tab :
1.Draw Arrondissment coordinates drawn
2.Draw Department coordinates after them (like superimpose)
Make the Department Transparent (reduce the opacity)
this procedure mix the border well, but the Hover on does still as per Department level .
this is svg vector Map and Each map piece is made up of coordinates
Code is complex and lengthy for Creation of Map , thats why I dont think can post all of it
this is the Main function which creates Bundary and add color to each piece Map
//path
for (var obj in mapObj.paths) {
var rObj = R.path(pathData[mapObj.paths[obj].path]).attr(attr);
//if url found the assign
if(mapObj.paths[obj].url !=null){
//rObj.attr({"href":mapObj.paths[obj].url});
if(mapObj.paths[obj].url.indexOf("alert") > 0){
rObj.attr({"href":mapObj.paths[obj].url});
}
else{
rObj.dblclick(function(e){
loadMap(this.data("qStr"));
});
rObj.click(function(e){
showPopup(this,currX,currY);
loadExternalData();
});
}
}
else{
rObj.click(function(e){
showPopup(this,currX,currY);
});
}
rObj.data("qStr", mapObj.paths[obj].url);
rObj.data("key", mapObj.paths[obj].key);
rObj.data("mType", mapObj.paths[obj].mType);
rObj.data("type", mapObj.paths[obj].type);
rObj.data("sTitle", mapObj.paths[obj].title);
rObj.data("name", mapObj.name);
rObj.data("showhide", "show");
rObj.data("zoom", mapObj.zoom);
rObj.data("parentId", mapObj.parentId);
rObj.data("title", mapObj.title);
rObj.color = Raphael.getColor();
rObj.data("hoverFill", "#3e5f43");
rObj.data("fill", "#fff");
rObj.data("childId", mapObj.paths[obj].key);
if(mapObj.paths[obj].cName=="city"){
rObj.data("className",mapObj.paths[obj].cName);
rObj[0].setAttribute('class', mapObj.paths[obj].cName);
}
else
{
rObj.data("className", mapObj.cName == "" ? mapObj.paths[obj].cName : mapObj.cName);
rObj[0].setAttribute('class', mapObj.cName == "" ? mapObj.paths[obj].cName : mapObj.cName);
}
rObj.hover(animateOver, animateOut);
rObj[0].id = mapObj.paths[obj].key;
rObj[0].style.cursor = "pointer";
rObj[0].setAttribute('title', mapObj.cName);
rObj[0].setAttribute('data-toggle', "tooltip");
rObj[0].setAttribute('data-placement', "left");
if (mapObj.zoom == 1) {
var box = rObj.getBBox();
var currPaperPosition = panZoom.getCurrentPosition();
var currPaperZoom = panZoom.getCurrentZoom();
var currHeight = R.height * (1 - currPaperZoom * 0.1);
rObj.animate({
transform: "t" + xdif + "," + ydif + "s" + mapZoom
}, 100);
}
}
}
I Just need to place hover property of lower layer on upper layer .Can this thing be done by Css and any other technique ?
In google maps or in the component you use for managing event check if the z-index of the Department is more high of that related to Arrondissment .. otherwise the mouse hover event in managed form the wrong polygon .. if you need you can change dinamically by setOption or a similar based on your need ..
yourPolygonObj.setOptions({ zIndex: 200 });