I want the violin chart (I'm using plotlyjs library) to be responsive. But also don't want it to compress so much (it is compressing according to the div it is kept in).
I have tried to turn the autosize property of violin to be false and then set the height and width. In this case the chart does not compress (stays the way I want it to be), but it loses its responsiveness. Is there a way to make this chart responsive yet no so compressed?
Here is my code:
<Plot
config = {{ displayModeBar: false }}
data={[
{
type: 'violin',
y: this.props.data,
points: 'none',
box: {
visible: true
},
boxpoints: false,
line: {
color: 'red'
},
opacity: 0.6,
meanline: {
visible: true
},
x0: "OEE"
}
]}
layout={{
title: "Comparison",
yaxis: {
zeroline: false
},
// autosize: false,
// height: 300,
// width: 500,
// responsive: true
}}
useResizeHandler= {true}
style= {{width: "100%", height: "100%"}}
/>
The div inside which violin is kept:
<div className="chart-wrapper" style={{ height: "35vh" }}>
<ViolinChart data={this.state.violinChartData} />
</div>
I got the solution to the above question.
PlotlyJS also provides a "margin" property for its charts. So providing margins will let you adjust the chart the way you want it to be
var layout = {
margin: {
l: 25,
r: 25,
b: 25,
t: 25
}
};
This is what i added to my code. Setting automargin = true will automatically increase the margin size.
More about this can be found here.
Related
I have got two queries, I am implementing tsParticles in my React application.
First one:.
<Particles
id="tsparticles"
options={{
background: {
color: {
value: "black",
},
},
fpsLimit: 60,
interactivity: {
detectsOn: "window",
events: {
onClick: {
enable: true,
mode: "push",
},
onHover: {
enable: true,
mode: "trail",
},
resize: true,
},
modes: {
bubble: {
distance: 400,
duration: 2,
opacity: 0.8,
size: 40,
},
push: {
quantity: 4,
},
repulse: {
distance: 200,
duration: 0.4,
},
},
},
particles: {
color:{
animation:{
enable:true,
speed:50,
},
value:"#f00"
},
links: {
shadow:{
blur:true,
color:"#00ff00"
},
triangles:{
frequency: 1
},
color: "random",
distance: 150,
enable: true,
frequency:1,
opacity: 0.5,
width: 1,
},
collisions: {
enable: true,
},
move: {
angle:{
offset: 45,
value: 90
},
attract:{
rotate:{
x:3000,
y:3000
}
},
gravity:{
acceleration: 9.81,
enable:false,
maxSpeed:1
},
direction: "none",
enable: true,
outMode: "bounce",
random: false,
speed: 6,
straight: false,
},
number: {
density: {
enable: true,
value_area: 1000,
},
value: 80,
},
opacity: {
value: 0.5,
},
shape: {
type: "circle",
},
size: {
random: true,
value: 5,
},
},
detectRetina: true,
}}
/>
There is a section of onHover and key value of mode in it. There are like 8 different modes to it, can be viewed in https://particles.matteobruni.it/ .
All other modes work fine but the trail mode when I use this code, am I missing some other properties to the Particles component?
Second one:
Also,
I have got two divs, one for the particle and the other for the text to display on top of it. I have achieved this using z-index and positions.
I need the canvas height to be dynamic that is occupy 100% height of its parent whatever the screen size is. I have tried doing this by including Particles component inside a div and keeping its height to 100% but the canvas height decreases with the decrease in the screen size.
Kindly help me, thank you :)
Wow, there's a lot to answer here, but I try to do my best.
First point, the config and mouse trail
The mouse trail needs more configuration, in the modes section of interactivity you have to configure the trail section.
You can see a sample here: https://codepen.io/matteobruni/pen/abdpbBY
If you need more documentation checkout the right section in documentation: https://particles.js.org/interfaces/_options_interfaces_interactivity_modes_itrail_.itrail.html
Second point, the canvas size
If you need a dynamic canvas size the best solution is to use the backgroundMode in the options root object
You can see a sample here: https://codepen.io/matteobruni/pen/MWeqxNL
The background mode if enabled sets the canvas style with a fixed position and the desired zIndex
You can see the documentation here: https://particles.js.org/interfaces/_options_interfaces_backgroundmode_ibackgroundmode_.ibackgroundmode.html
If you are using the backgroundMode, the better results are obtained without setting any style to the containing div (the tsParticles target/container)
When creating a path using dagre, the whole nodes accumulate in one position. How can we set default positions for nodes ( Cytoscape js without react works fine) instead of setting position separately using position attribute for nodes.
const layout = {
name: "dagre",
rankDir: "LR"
}
pageData = < CytoscapeComponent
elements = {
CytoscapeComponent.normalizeElements({
nodes: nodess,
edges: edgess,
layout: layout,
})
}
pan = {
{
x: 200,
y: 200
}
}
autounselectify = {
true
}
userZoomingEnabled = {
false
}
boxSelectionEnabled = {
false
}
style = {
{
width: "1200px",
height: "1000px"
}
}
/>
return (
< div
{
pageData
}
< /div>
);
Expected result:
Current result:
There is a way to force the calculation of node positions as they are added. This is also useful when the elements of the graph change dynamically with the state of the component and the graph has to be rendered again with updated node positions.
<CytoscapeComponent
cy={(cy) => {
this.cy = cy
cy.on('add', 'node', _evt => {
cy.layout(this.state.layout).run()
cy.fit()
})
}}
/>
Here is what worked for me:
cytoscape.use(fcose)
//..then in my render...
<CytoscapeComponent
elements={elements1}
layout={{
animate: true,
animationDuration: undefined,
animationEasing: undefined,
boundingBox: undefined,
componentSpacing: 40,
coolingFactor: 0.99,
fit: true,
gravity: 1,
initialTemp: 1000,
minTemp: 1.0,
name: 'fcose',
nestingFactor: 1.2,
nodeDimensionsIncludeLabels: false,
nodeOverlap: 4,
numIter: 1000,
padding: 30,
position(node) {
return { row: node.data('row'), col: node.data('col') }
},
randomize: true,
refresh: 20,
}}
style={{ width: '600px', height: '300px' }}
/>
You may try "Euler" layout instead of "Dagre" layout
I need many very small charts on one page, but if I set width 50px and height 25px I do not see chart. Also I will thanks of suggestions other libraries to create more than 200 charts on page without performance problem.
I tried set width and height via css on parent div.
https://codesandbox.io/s/m5pl96l8op
import React from "react";
import ReactDOM from "react-dom";
import Chart from "react-chartist";
import "./styles.css";
function App() {
return (
<div className="App">
<Chart
className="chart"
data={{
series: [[1, 3, 2, 8, 4, 12, 27, 16]]
}}
type="Line"
options={{
fullWidth: true,
width: "50px",
height: "25px",
showPoint: false,
axisY: {
showGrid: false,
showLabel: false
},
axisX: {
showGrid: false,
showLabel: false
}
}}
/>
</div>);
}
I expect very small chart, but I does not see any chart.
In Chartist's docs, you'll find all the options available and their default values.
Your issue here is that there are margins and paddings everywhere by default, which leaves very little space for your data. Here are the options you can use to remove any extra space:
https://codesandbox.io/s/4lxl0qvly9
function App() {
// We'll use this multiple times, so declare it here
const series = [1, 3, 2, 8, 4, 12, 27, 16];
return (
<div className="App">
<Chart
className="chart"
data={{
series: [series]
}}
type="Line"
options={{
fullWidth: true,
width: "50px",
height: "25px",
low: Math.min(...series), // Remove space around min and max values
high: Math.max(...series), // Remove space around min and max values
chartPadding: {
// Remove all padding
top: 0,
right: 0,
bottom: 0,
left: 0
},
showPoint: false,
axisY: {
offset: 0, // Remove any offset
position: "start", // Remove any bottom margin
showGrid: false,
showLabel: false
},
axisX: {
offset: 0, // Remove any offset
position: "start", // Remove any left margin
showGrid: false,
showLabel: false
}
}}
/>
</div>
);
}
I have a bootstrap carousel with 2 slides. Both the slides uses bootstrap grids of 2x2 to display charts on them. They are working fine , however I am trying to implement responsive media queries and can't seem to make it work. I used baseOptions and media options to define but the charts do not load up and the console doesn't show any error.
I have tried to define the <div> container with inline style width and height i.e. style="width: 100%;height:400px;" and I have also tried to define the width and height in CSS like so-
.mychart {
width: 100%;
height: 400px;
}
The javascript looks like below.
<div id="chart1" style="width: 100%;height:400px;"></div> //with inline style
<div id="chart1" class="mychart"></div> //with CSS class
var myChart1 = echarts.init(document.getElementById('chart1'));
var lpnArr = [101, 43, 10, 250];
option = {
title : {
text: 'My data Pie',
subtext: 'Data as of last batch',
x:'center'
},
tooltip : {
trigger: 'item',
formatter: "{b} : {c} ({d}%)"
},
legend: {
orient : 'vertical',
x : 'left',
data:['Processed','Unprocessed','In RIB','Errors']
},
color: ['#4bc14f','#ff7f50','#da70d6','#d8316f'],
toolbox: {
show : true,
feature : {
mark : {show: false},
dataView : {show: false},
magicType : { show: false},
dataZoom : { show : false},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : true,
series : [
{
name:'Processed',
type:'pie',
radius : ['50%', '70%'],
startAngle : 230,
center: ['35%', '50%'],
itemStyle : labelFormatter, //custom formatter
data: lpnArr //load chart with data array lpnArr
}
]
}
var mediaQuery = [
{
option: {
series: [
{
radius: ['50%', '70%'],
center: ['35%', '50%']
}
]
}
},
{
query: {
minAspectRatio: 1
},
option: {
series: [
{
radius: ['50%', '70%'],
center: ['35%', '50%']
}
]
}
},
{
query: {
maxAspectRatio: 1
},
option: {
series: [
{
radius: ['50%', '70%'],
center: ['50%', '35%']
}
]
}
},
{
query: {
maxWidth: 500
},
option: {
series: [
{
radius: ['50%', '70%'],
center: ['50%', '35%']
}
]
}
}
];
myChart1.setOption({baseOption : option,
media : mediaQuery});
if I use it without the media query it works just fine. like this
myChart1.setOption(option);
Using the media query, as per the documentation along with baseOptions and media, the charts simply don't load and it doesn't show me any error in the console as well, so I am not sure if I am using it correctly or not.
By the way, I also have this in the end of the script to be able to resize the charts when the window is resized but then I realized that this is not truly responsive -
$(window).on('resize', function(){
myChart1.resize();
});
The bootstrap chart elements are <div> elements within other div with a class of BS container-fluid. The carousel code can be found in this JSFiddle.
Media query was introduced in echarts version 3, whereas I have been using version 2 and thus it wasn't working. It's extremely odd that using media with version 2 doesn't show any kind of error, neither does baseOption show any error so I was left scratching my head. Documentation isn't clear enough to say that media queries is only supported in version 3. So after scouring through the code and GitHub threads for hours and trying out all their js versions I came to this conclusion.
The downside of using version 3 echarts is that it is missing the "Tree" chart type and it's a lot more pickier than any prior version. Also, it's twice as much slower than version 2.
I am using the excellent Fabric.js to draw some text in a canvas. When I specify a custom size ( let's say a 200x200 rectangle) to my IText Object, it seems that Farbric.js force the width and the height of the object to fit around the text.
var t = new fabric.IText("Hello world !", {
top: 100,
left: 100,
width: 200,
height:200,
backgroundColor: '#FFFFFF',
fill: '#000000',
fontSize: 12,
lockScalingX: true,
lockScalingY: true,
hasRotatingPoint: false,
transparentCorners: false,
cornerSize: 7
});
Here is a Fiddle with my problem : http://jsfiddle.net/K52jG/4/
In this example, I want the "Hello World!" text to be in a 200x200 box. Is it possible to do that, and how ?
OK, so because it is not possible, the best way I found to is to nest the IText box in a Rectangle object, using a Group
var r = new fabric.Rect({
width: 200,
height: 200,
fill: '#FFFFFF',
});
// create a rectangle object
var t = new fabric.IText("Hello world !", {
backgroundColor: '#FFFFFF',
fill: '#000000',
fontSize: 12,
top : 3,
});
var group = new fabric.Group([ r, t ], {
left: 100,
top: 100,
lockScalingX: true,
lockScalingY: true,
hasRotatingPoint: false,
transparentCorners: false,
cornerSize: 7
});
Example in this Fiddle : http://jsfiddle.net/4HE3U/1/
Note : I have to set a "top" value to the text because it goes out of the box. The value seem to be : fontSize / 4