Combining of views using coordinates and zstack - swiftui

i have an issue with ordering, combining and positioning of my solid shapes and text
the task is simple enough, but while im completely newbie in swfitui i cannot do it for my self
task: place solid shapes with zstack relative by their parrent using coordinates (including text of each shape) and apply isometric/perpective modifier
i will be glad for explanations and hints
this is what i have done for now
works without modifiers
and no with isometric modifier
struct ContentView: View {
#ObservedObject var datas = ReadData()
//MagnificationState
//DragState
//#GestureState
//#State viewMagnificationState
//#GestureState
//#State viewDragState
//magnificationScale
//translationOffset
//#State popoverState
//#State selectedShape
var body: some View {
//magnificationGesture
//dragGesture
//magnificationGesture.simultaneously
GeometryReader { geometry in
ZStack(alignment: .topLeading) {
MainShape(showingPopover: $popoverState,
setCurrentShape: $selectedShape,
alldatas: datas.pokedex)
}
.scaleEffect(magnificationScale)
.offset(translationOffset)
//.position(x: geometry.size.width / 2, y: geometry.size.height / 2)
//.gesture(both)
//popover
}
.edgesIgnoringSafeArea(.all)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
struct MainShape: View {
let alldatas: [PokedexElement]
var body: some View {
ForEach(alldatas, id: \.id) { shape in
ZStack(alignment: .topLeading) {
Text(shape.metaProperties.name)
.font(.system(size: 20))
.zIndex(2)
.offset(x: shape.metaProperties.offset.x, y: shape.metaProperties.offset.y)
Rectangle()
.cornerRadius(shape.id == 1 ? 55 : 10)
.foregroundColor(chooseColor(shape.metaProperties.color))
.offset(x: shape.metaProperties.offset.x, y: shape.metaProperties.offset.y)
.frame(
width: shape.metaProperties.size.width,
height: shape.metaProperties.size.height
)
.isometric()
.zIndex(1)
.onTapGesture {
self.showingPopover = true
self.setCurrentShape = shape.id
}
}
}
}
}
data:
[
{
"id": 1,
"parentId": 0,
"baseProperties": {
"name": "",
"descr": "",
"contacts": ""
},
"metaProperties": {
"name": "root",
"status": true,
"type": "plain",
"size": {
"width": 350,
"height": 350
},
"offset": {
"x": 0,
"y": 0
},
"color": "blue"
}
},
{
"id": 2,
"parentId": 1,
"baseProperties": {
"name": "object 1",
"descr": "",
"contacts": ""
},
"metaProperties": {
"name": "child 1",
"status": true,
"type": "imobject",
"size": {
"width": 50,
"height": 50
},
"offset": {
"x": 50,
"y": 50
},
"color": "red"
}
},
{
"id": 3,
"parentId": 1,
"baseProperties": {
"name": "object 1",
"descr": "",
"contacts": ""
},
"metaProperties": {
"name": "child 2",
"status": true,
"type": "imobject",
"size": {
"width": 100,
"height": 50
},
"offset": {
"x": 100,
"y": 50
},
"color": "green"
}
}
]
and modifiers…
extension View {
func chooseColor(_ name: String) -> Color {
switch name {
case "red":
return Color.red
case "blue":
return Color.blue
case "brown":
return Color.brown
case "green":
return Color.green
case "yellow":
return Color.yellow
case "white":
return Color.white
default :
return Color.black
}
}
func perspective() -> some View {
self
.rotation3DEffect(.degrees(45), axis: (x: 1, y: 0, z: 0))
}
func isometric() -> some View {
self
.rotationEffect(Angle.init(degrees: 45))
.scaleEffect(y: 0.5)
}
}

task was easy, instead of using regular solid shapes with "magic methods from black box" do it all manually
convert decart to iso and place it whatever you want together with text or anything else and offset will be fine

Related

Chart.js - How to move x axis tick marks position to above the x axis

I drew a line chart and want to move x axis tick marks position, but I can not find related configuration. Please see the picture below.
AS-IS/TO-BE
Here is my code
<script src="https://cdn.jsdelivr.net/npm/chart.js/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js">
<canvas id="myChart" style="height:500px"></canvas>
chart = new Chart(document.getElementById("myChart"), {
type: 'line',
data: {
datasets: [{
label: "Count",
pointStyle: 'circle',
showLine: true,
fill: false,
lineTension: 0,
borderColor: '#7265ce',
pointRadius: 4,
pointBorderWidth: 1,
pointBackgroundColor: '#7265ce',
data: data
}]
},
options: {
parsing: {
xAxisKey: 'timestamp',
yAxisKey: 'value'
},
spanGaps: false,
responsive: false,
scales: {
x: {
bounds: 'ticks',
type: 'time',
time: {
parser: 'yyyyMMddHHmmss',
unit: 'minute',
stepSize: 5,
displayFormats: {
minute: 'HH:mm',
second: 'mm:ss'
}
},
title: {
display: false,
text: 'Timestamp'
},
grid: {
drawOnChartArea: false,
lineWidth: 1
},
ticks: {
display: true,
color: '#cecece'
}
},
y: {
type: 'linear',
display: true,
ticks: {
padding: 10,
autoSkip: true,
maxTicksLimit:2,
color: '#cecece'
},
title: {
display: false,
text: 'Count',
align: 'end'
},
grid: {
drawOnChartArea: false
},
}
}
}
});
});
let data = [
{ "timestamp": "20230109150000", "value": 10 },
{ "timestamp": "20230109150100", "value": 17 },
{ "timestamp": "20230109150200", "value": 92 },
{ "timestamp": "20230109150300", "value": 60 },
{ "timestamp": "20230109150400", "value": 50 },
{ "timestamp": "20230109150500", "value": 91 }
];
Is it possible?
Is there any configuration in chartjs?
I'm using v3.9.1
Sorry for my poor english.

GBP currency conversion of Apex Charts data labels

I'm learning to work with Apexcharts and need to show the labels (Y axis labels an data labels) as currency (GBP) but can't seem to find the right approach. I have looked at the locale code, but really not sure how to integrate this into my chart.
I'm trying to ensure that 1000 become 1,000 etc.
Below is the chart code
<script>
var options = {
series: [
{
name: "Price in £s",
data: [1000, 2000, 2500, 3000, 4800, 6000]
}
],
chart: {
height: 350,
type: 'bar',
id: 'areachart-2',
dropShadow: {
enabled: true,
color: '#000',
top: 18,
left: 7,
blur: 10,
opacity: 0.2
},
toolbar: {
show: false
}
},
colors: ['#f6564d', '#545454'],
dataLabels: {
enabled: false,
textAnchor: 'middle',
formatter: function(val, index) {
return val.toFixed(0);
}
},
stroke: {
curve: 'straight'
},
title: {
text: '',
align: 'left'
},
grid: {
borderColor: '#f1f1f1',
row: {
colors: ['#fff', 'transparent'], // takes an array which will be repeated on columns
opacity: 0.5
},
},
markers: {
size: 100
},
xaxis: {
categories: ['01/05/22','01/06/22','01/07/22','01/08/22','01/09/22','01/10/22'],
title: {
text: 'Month'
}
},
yaxis: {
min:00,
title: {
text: 'Price in GBP',
},
},
legend: {
position: 'top',
horizontalAlign: 'right',
floating: true,
offsetY: 100,
offsetX: 100
}
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
</script>
In yaxis add labels formatter
labels:{
formatter: (value) => {
return `${numberWithCommas(value)} GBP`;
},
},
And use this regex to add commas
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
Axes labels formatting can be controlled by yaxis.labels.formatter and xaxis.labels.formatter.
yaxis: {
labels: {
formatter: function (value) {
return value + "$";
}
},
},
xaxis: {
labels: {
formatter: function (value) {
return value;
}
}
}

How to get gradient in treemap using echarts

I have a single hierarchy and based on values, I want gradient based on values on my map. I have used echarts for this. The solution given in their examples is hard to implement for getting a gradient. I have used React JS to achieve this. Here's my code along with json here -
import React, {useEffect} from 'react';
// import the core library.
import ReactEchartsCore from 'echarts-for-react/lib/core';
import ReactEcharts from "echarts-for-react";
// then import echarts modules those you have used manually.
import echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/treemap';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
var treemapData = [
{
"name": "abcdaaaaaaaaaaaaaaaaa",
"value": 250,
},
{
"name": "xyzxyzxyzxyzxyzzz",
"value": 525,
},
{
"name": "mnopmnopmnop",
"value": 1120,
},
{
"name": "vsuuuuuuuuuvu",
"value": 216,
},
{
"name": "1232342343434",
"value": 400,
},
{
"name": "timetimetime",
"value": 297,
},
{
"name": "placeplaceplace",
"value": 208,
},
{
"name": "countrycountry",
"value": 1203,
}
];
function TreemapEcharts() {
return (
<ReactEcharts
option={{
series: [{
type: 'treemap',
data: treemapData,
label: {
normal: {
textStyle: {
ellipsis: true
},
position: 'insideCenter',
formatter: function (params) {
var arr = [
'{name|' + params.name + '}',
'{value|' + params.value + '}'
];
return arr.join('\n');
},
rich: {
name: {
fontSize: 14,
color: '#fff'
},
value: {
fontSize: 14,
color: '#fff'
},
}
}
},
levels: [
{
itemStyle: {
normal: {
borderWidth: 2,
borderColor: '#fff',
gapWidth: 2
}
}
},
],
}]
}}
style={{ height: '300px', width: '50%' }}
/>
)
}
export default TreemapEcharts
Please let me know how can we add a gradient where color varies from darkest shade to lightest shade of one color here.
In case anyone is still wondering, you should take a look at their document regarding level: https://echarts.apache.org/en/option.html#series-treemap.levels.
Basically, you need to configure a color range and set colorMappingBy to "value". You should have something like this for your level config:
{
color: ["#942e38", "#aaa", "#269f3c"],
colorMappingBy: "value",
itemStyle: { ... }
}
To fine-tune your visualization, you can convert your value to an array, with the second element in the array being a value scaled to the desired saturation and map your color to that value by setting visualDimension to 1 (index value of the element the array), and manually set visualMin and visualMax values.
You can also take a look at their example: https://echarts.apache.org/examples/zh/editor.html?c=treemap-visual.

Elasticsearch nested aggregation with range aggregation

I am very new to ElasticSearch and trying to figure out a situation
where I have to show particular JSON data from Elasticsearch. Please
see below code
def bucket_for_order_amount(buckets, aggregations)
buckets['order_range'] = {
range: {
field: :total,
keyed: true,
ranges: [
{ to: 25.0 },
{ from: 25.0, to: 50.0 },
{ from: 50.0, to: 75.0 },
{ from: 75.0, to: 100.0 },
{ from: 100.0 }
]
}
}
end
This will return JON response:
"report": {
"order_range": {
"buckets": {
"*-25.0": {
"to": 25,
"doc_count": 0
},
"25.0-50.0": {
"from": 25,
"to": 50,
"doc_count": 0
},
"50.0-75.0": {
"from": 50,
"to": 75,
"doc_count": 0
},
"75.0-100.0": {
"from": 75,
"to": 100,
"doc_count": 0
},
"100.0-*": {
"from": 100,
"doc_count": 2
}
}
}
I have a situation where I have to show the users listing inside the doc_count if any user exists in that range but I am not sure which
aggregation need to use to achieve this response.
The response would be like this:-
"*-25.0": {
"to": 25,
"doc_count": 2
{
user1,
user2
},
},
You can use the top_hits sub-aggregation for that purpose:
def bucket_for_order_amount(buckets, aggregations)
buckets['order_range'] = {
range: {
field: :total,
keyed: true,
ranges: [
{ to: 25.0 },
{ from: 25.0, to: 50.0 },
{ from: 50.0, to: 75.0 },
{ from: 75.0, to: 100.0 },
{ from: 100.0 }
]
},
aggs: {
users: { top_hits: {} }
}
}
end

Zingchart bar chart starting at y axis -50

When I am trying to create a barchart for mobile, the y axis actually starts from the middle of the screen, hence i am unable to see my chart completely. For viewing the chart, i need to zoom out the device by 20%, or i need to set a plotarea y value as -50. Can someone let me know where am i going wrong?
Graph is seen when added the below code:
plotarea:{
adjustLayout: 1,
marginTop:'dynamic',
backgroundFit: "y",
"y": -50
}
Attached image can be seen here:
1st: Without zoom, 2nd: With 20% zoom out, 3rd: with y as -50
Complete code is here:
var myConfig = {
type: "bar",
backgroundColor: "transparent",
plotarea:{
adjustLayout: 1,
marginTop:'dynamic',
backgroundFit: "y"
//"y": -50
},
plot:{
"rules": [
{
"rule": "%i==0",
"background-color": "#ACD373",
"placement": "in"
},
{
"rule": "%i==1",
"background-color": "#B7B7B7",
"placement": "in"
},
{
"rule": "%i==2",
"background-color": "#FF6E5B",
"placement": "in"
},
{
"rule": "%i==3",
"background-color": "#6DCFF6",
"placement": "in"
},
{
"rule": "%i==4",
"background-color": "#F9AD81",
"placement": "in"
},
{
"rule": "%i==5",
"background-color": "#898989",
"placement": "in"
}
],
valueBox:{
fontColor: "#fff",
connector: {
lineWidth: 1
},
"text": "%v",
"font-size": 20,
"font-weight": "normal",
"font-style": "normal"
}
},
"scale-x": {
"label":{
"text":[],
"color": "#fff"
},
item:{
color: "#fff",
},
"guide":{
"line-width":0
},
zooming: true,
"values":[]
},
"scale-y":{
"line-color":"none",
"item":{
"visible": false
},
"tick":{
"line-color":"none"
},
"guide":{
"line-color":"#4A6B89",
"line-width":1,
"line-style":"solid",
"alpha":1
}
},
labels:[
{
//text:"Hold SHIFT to detach<br>multiple slices",
textAlign: "left",
fontColor: "#fff"
}
],
series: [{values:[]}]
};
The same code works perfectly for another chart with the same data set and same width height for the div which is rendering this chart.
Also, i can't make the y value as -50 as i have bound the chart top open another chart on clicking any of the bars. On making y as -50, i am unable to click the bars.
I have updated your tags to be appropriate to your environment, coldfusion. I assume you are using cfchart as well. This means not all properties persist across.
I have adjusted a few properties. They mostly have to do with margins within the plotarea object. My best suggestion is try playing around with margins if margin:'dynamic' does not apply for your build.
demo link
var myConfig = {
type: "bar",
backgroundColor: "#1D3557",
plotarea:{
adjustLayout: 1,
margin:'dynamic',
},
plot:{
"rules": [
{
"rule": "%i==0",
"background-color": "#ACD373",
"placement": "in"
},
{
"rule": "%i==1",
"background-color": "#B7B7B7",
"placement": "in"
},
{
"rule": "%i==2",
"background-color": "#FF6E5B",
"placement": "in"
},
{
"rule": "%i==3",
"background-color": "#6DCFF6",
"placement": "in"
},
{
"rule": "%i==4",
"background-color": "#F9AD81",
"placement": "in"
},
{
"rule": "%i==5",
"background-color": "#898989",
"placement": "in"
}
],
valueBox:{
fontColor: "#fff",
connector: {
lineWidth: 1
},
"text": "%v",
"font-size": 20,
"font-weight": "normal",
"font-style": "normal"
}
},
"scale-x": {
"label":{
"text":'Version',
"color": "#fff"
},
item:{
color: "#fff",
},
"guide":{
"line-width":0
},
zooming: true,
"values":[]
},
"scale-y":{
"line-color":"none",
"item":{
"visible": false
},
"tick":{
"line-color":"none"
},
"guide":{
"line-color":"#4A6B89",
"line-width":1,
"line-style":"solid",
"alpha":1
}
},
zoom: {
preserveZoom:true,
},
labels:[
{
//text:"Hold SHIFT to detach<br>multiple slices",
textAlign: "left",
fontColor: "#fff"
}
],
series: [{values:[15,25,35,45,35,45]}]
};
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>
</head>
<body>
<div id="myChart"><a class="zc-ref" href="https://www.zingchart.com">Powered by ZingChart</a></div>
</body>
</html>
It might be because, either you would have the font-size that makes chart extend the screen size or try changing the margin it might help, I tried it in the past but with no luck.