d3 force directed graph & svelte reactive statement - d3.js

I tried to make a simple d3 force-directed graph with the svelte reactive statement, but apparently, it's not working together.
1st example, this is the simplest way I make the graph (working REPL):
<script>
import * as d3 from 'd3'
import { onMount } from 'svelte'
import data from './data.json'
let svg,
width = 500,
height = 400,
links, nodes
let simulation = d3.forceSimulation(data)
</script>
<svg
bind:this={svg}
width={width}
height={height}
viewBox="{-width/2} {-height/2} {width} {height}"
>
{#each data as node}
<g class="g-nodes" >
<circle bind:this={nodes}
fill="cornflowerblue"
r="5"
cx={node.x}
cy={node.y}
></circle>
</g>
{/each}
</svg>
2nd example, I want to add some force with reactive statement to it, let's say forceX, and it doesn't work, until I add simulation.tick(100) or any number > 0 inside the .tick() (working REPL):
<script>
// the before part is still the same
let simulation = d3.forceSimulation(data)
$: simulation.force("x", d3.forceX(0)) // not working, the circle stay at the initial position
$: simulation.tick(100) // the force worked, but not animating from the initial position
</script>
<!-- the rest of svg is still the same -->
3rd example, I tried the .on("tick") with function. The function is fired (I only give a console.log to test if the tick working.) but I have no idea how to pass the modified data to the {#each} block. Looking at the console.log(data) inside the update function, the x and y data are changing every tick, but not updating the actual circle position. (working REPL):
<script>
// the before part is still the same
let simulation = d3.forceSimulation(data)
function update() {
console.log(data)
return data // I don't know if it's the correct way, but still not working tho
}
$: simulation.force("x", d3.forceX(0))
$: simulation.on("tick", update)
</script>
<!-- the rest of svg is still the same -->
data.json
[
{value: 10},
{value: 12},
{value: 15},
{value: 8},
{value: 7},
{value: 12},
{value: 25},
{value: 20},
{value: 16},
{value: 13},
{value: 5},
{value: 7},
{value: 8},
{value: 10},
{value: 12},
{value: 14},
{value: 24},
{value: 23},
{value: 22},
{value: 11},
]

The simplest way to address your problem in step #3 is to declare a displayData array, to copy over data into displayData inside your update function, and to iterate your #each block over displayData.
data being an import variable, you cannot directly reassign to it, and because you cannot reassign to it, it is not reactive and data updates do not trigger a re-render.
By assigning data to displayData in your update function (which will run on every tick), you will trigger a re-render of your #each block (provided you now iterate over displayData).
Working REPL

Related

Html blurry on rotation: react-three/drei

So I can't seem to get html to rotate with react-three/drei without it being extremely blurry. It won't blur at smaller sizes, but whenever I add more text it reaches a point where it just blurs up like below.
If there's a more standard way to rotate an html container, please let me know and i'll just that because i'm losing my mind here.
Code:
<Html
as="div"
position={[0, 0, 0]}
rotation={[0, 0.4, 0]}
transform
style={{
backgroundColor: "green",
borderRadius: 4,
}}
>
<div>
{"Testingsss"}
</div>
...
</Html>
Without rotation:
With rotation:

Vuejs how to use Vue-slick in childs component?

i need to use more than one slider in my site, i done it by import Vueslick to child component one by one, but i want to import only one Slick library, this is my idea:
<pre><code>
<template>
<div>
<slider :slickOptionsSlider='slickOptionsSlider'></slider>
<blogsuckhoe :slickOptionsBlogsuckhoe='slickOptionsBlogsuckhoe' ></blogsuckhoe>
</div>
</template>
<script>
data() {
//import slick vĂ  child component
return {
slickOptionsSlider: {
autoplay:true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
dots:false,
arrows:false,
},
slickOptionsBlogsuckhoe: {
autoplay:true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
dots:false,
arrows:false,
},
};
}
</script>
</code></pre>
sure, it is not working. Can you help me ? Thank you . Im sorry for my bad English.
You can register it as a global component.
app.js
Vue.component('vue-slick',require('vue-slick').default);
Then use it anywhere inside your root element, within a component or directly in a blade template.
SomeComponent.Vue
<vue-slick :options='options'></vue-slick>
some.blade.php
<vue-slick :options='#json($options)'></vue-slick>

Morris donut graphs. Very long and small labels

I have very long labels on my morris donut graphs.
Because of their long it's very hard to read.
I would like to have some kind of popup with label when I hover on that text. But there are no css classes to bind a handler.
js code:
Morris.Donut({
element: 'donut-example',
data: [
{label: "Download SalesD DDDDDDDDDDDDDDDDD", value: 12},
{label: "In-Store Sales AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", value: 30},
{label: "Mail-Order Sales VVVVVVVVVVVVVVV", value: 20}
]
});
I've tried formatter, but it is not a solution.
Please give me some help.
Here is example
After a long time without any answer I decide to post my own solution. I doesn't do exactly what I've asked for, but supply readable solution.
It was done with label below the donut, instead of inside donut circle.
Here is working solution on JS Bin
Below You can see a screenshot of working in app:
Here is the code:
JS:
Morris.Donut({
element: 'morrisDonutChart',
data: [
{label: "Download SalesD DDDDDDDDDDDDDDDDD", value: 12},
{label: "In-Store Sales AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", value: 30},
{label: "Mail-Order Sales VVVVVVVVVVVVVVV", value: 20}
]
});
$( "#morrisDonutChart" ).mouseover(function() {
prepareMorrisDonutChart();
});
$( document ).ready(function() {
prepareMorrisDonutChart();
});
function prepareMorrisDonutChart() {
$("#morrisDonutChart tspan:first").css("display","none");
$("#morrisDonutChart tspan:nth-child(1)").css("font-size","40px");
var isi = $("#morrisDonutChart tspan:first").html();
$('#morrisDonutChartSpan').text(isi);
}
HTML head:
<script src="https://ajax.googleapis.com/ajax/libs/mootools/1.5.0/mootools-yui-compressed.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script src="http://cdn.oesmith.co.uk/morris-0.4.1.min.js"></script>
HTML body:
<div id="morrisDonutChart"></div>
<div class="alert alert-info" role="alert">
<span id="morrisDonutChartSpan"></span>
</div>
I hope this will help someone.

paper-dropdown-menu overlay not working

I've a paper-dropdown-menu element. How can I show a different selected label, than valueattr is targeting at?
<link rel="import" href="components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="components/paper-item/paper-item.html">
<polymer-element name="my-dropdown-element" attributes="selectedModus">
<template>
<paper-dropdown-menu label="Modus" on-core-select="{{modusSelect}}">
<paper-dropdown class="dropdown">
<core-menu class="menu" selected="{{selectedModus}}" valueattr="val">
<template repeat="{{d in data}}">
<paper-item val="{{d.val}}">{{d.text}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
</template>
<script>
Polymer('my-dropdown-element', {
data: [],
ready: function() {
this.data = [];
var entry = {
val: 0,
text: 'Aus'
};
this.data.push(entry);
entry = {
val: 1,
text: 'Ein'
};
this.data.push(entry);
entry = {
val: 2,
text: 'Auto'
};
this.data.push(entry);
entry = {
val: 3,
text: 'Auto (Absenken)'
};
this.data.push(entry);
}
});
</script>
</polymer-element>
When I set selectedModus = 2, the highlighted Item in the opened dropdown is auto. This is correct. But in the dropdown label there is always 0, 1, 2, 3 and not the text representation of the dropdown.
Please help me
Thanks.
edit:
I've deleted all Polymer components from my project. Then I've updated all dependencies via bower from the master's branch of each component.
Now the correct label is showing in the closed dropdown. But clicking on the arrows, doesn't open the drop down menu. I'm getting an error in the timinig-utilities.js which can be traced back to paper-dropdown-transistion.html line 152.
Very strange.
Ok i've found the answer to my problem. It seems to be a bug in the current core-animation\web-animations.html. The change mentioned here
https://github.com/zenorocha/core-animation/commit/0d047ce11e5e6b25c02f1d89b2e7aa53588d7316 worked for me.

jqPlot - Pie legend too tall when there are many legend items

I'm using jqPlot to create a pie chart with a legend. Part of my jqPlot pie options look as follows:
seriesDefaults: {
renderer: $.jqplot.PieRenderer,
rendererOptions: {
padding: 10,
showDataLabels: true,
dataLabelFormatString: '%.2f%%',
sliceMargin: 2,
startAngle: -90
}
},
legend: {
show: true,
location: 'e',
placement: 'outside',
xoffset: 1,
fontSize: '11px',
rowSpacing: '10px',
textColor: '#222222',
fontFamily: 'Lucida Grande, Lucida Sans, Arial, sans-serif'
}
Recently I've come across a case where there are many legend items (e.g., 21), which makes my legend box too tall. I'm wondering if there is a way to either
have a vertical scroll bar within the legend box
display the legend items in multiple columns (preferable)
I've tried setting the following properties:
numberRows
numberColumns
which I found from this page:
$.jqplot.PieRenderer options
however they don't seem to make any changes.
Would anybody be able to provide me with a good solution to this problem?
Try to go with the provided column/row settings. I double-checked personally that this settings do work. Just make sure that in legend you set the numberColumns or numberRows inside rendererOptions, like:
legend: {
show: true,
location: 'ne',
rendererOptions: {numberColumns: 2}
}
If this doesn't work then I must say some other bug must be hiding in your code, then let us see the code so we can find and squash the bug together :)

Resources