I try to do a highchairs code to make a Moving line with reality time ( manual action)
the first point it the same that standard line and can't be Moving
the other point can be Moving right or left
when I move the second point, it ok the other point move too
but when I move the 3 points (or more ) the 2nd point move too and it's not ok, I need the behind point not move
I try to do with groupid solution…
I select x point, the point x+1,x+2,x+3 move too but the point x-1, x-2 don't group with ( so don't move)
how can I group and ungrouped when I move point?
how can I do to limit min selected point to not move left behind x-1 point?
thank for your help
i do this code : jsfiddle.net/arawn45/60bdzu4o/14/
a piece of code :
groupId: 'Group A',
i find a solution to limite move point Under data
if (Highcharts.dateFormat('%e - %b - %Y', new Date(this.x)) ==
(Highcharts.dateFormat('%e - %b - %Y', Date.UTC(1970, 10, 9)))) {
setDragStatus('erreur condition 1 '+Highcharts.dateFormat('%e - %b - %Y', new Date(this.x))+' ');
return false;
}
i dont know how to do that
if (Highcharts.dateFormat('%e - %b - %Y', new Date(this.x)) <
(date point-1 )
…
thanks for your help
In mouseOver event function you can reduce the number of dragged points by changing groupId property for points with lower x value:
series: [{
point: {
events: {
mouseOver: function() {
var points = this.series.points;
points.forEach(function(point, i) {
if (i && point.x < this.x) {
point.update({
groupId: false
}, false);
}
}, this);
},
mouseOut: function() {
var points = this.series.points;
points.forEach(function(point, i) {
if (i) {
point.update({
groupId: 'Group A'
}, false);
}
});
}
}
},
...
}]
Live demo: http://jsfiddle.net/BlackLabel/apqbd3ft/
API Reference:
https://api.highcharts.com/highcharts/series.scatter.point.events.mouseOver
https://api.highcharts.com/highcharts/series.scatter.point.events.mouseOut
https://api.highcharts.com/class-reference/Highcharts.Point#update
thanks very much
it look like what i want to do
juste add a limite when i move point to left, before this point.date than point-1.date.
thanks
Related
I have a path that draw a circle whose origin is in the "west" side, then I split by removing the top and bottom. Then I get three sub-paths:
Top-left 1/4 circle
Right half circle
Bottom-left 1/4 circle
But even visually 1 and 3 looks like a flipped 2, 1 and 3 are actually two sub-paths. How do I optimize this? I've tried smooth(), flatten() and simplify() and all not work.
Here is the sketch.
Based on your simplified case, you just have to build a new path composed of all your sub paths segments.
In order to optimize the resulting path a bit, you can skip the first segment of path B and only keep its handle out, since it's the same than path A last segment.
Depending on your use case, you could also, with the same logic, skip the last segment of path B since it's the same than path A first segment and make sure that the resulting path is set to closed.
Here is a sketch demonstrating a possible implementation.
const compoundPath = project.importJSON(
['CompoundPath', { 'applyMatrix': true, 'children': [['Path', { 'applyMatrix': true, 'segments': [[50, 700], [0, 700], [0, 600], [50, 600]] }], ['Path', { 'applyMatrix': true, 'segments': [[50, 600], [100, 600], [100, 700], [50, 700]] }]] }]
);
compoundPath.strokeColor = 'black';
project.activeLayer.addChild(compoundPath);
const subPaths = [];
compoundPath.children.forEach((child, i) => {
subPaths.push(
child
.clone()
.translate(0, 150)
.addTo(project.activeLayer)
);
});
const assembledPath = assembleSubPaths(subPaths);
assembledPath.strokeColor = 'black';
function assembleSubPaths(subPaths) {
const path = new Path();
subPaths.forEach((subPath) => {
subPath.segments.forEach((segment, segmentIndex) => {
const isFirstSegment = segmentIndex === 0;
if (path.segments.length === 0 || !isFirstSegment) {
path.add(segment);
} else {
path.lastSegment.handleOut = segment.handleOut;
}
});
subPath.remove();
});
return path;
}
According to my understanding, project.getItems({selected: true}) returns wrong results: I'm selecting a curve, it returns the parent Path: Sketch
Try clicking on a curve or a segment. Whole path will be moved. Then try changing the behavior by setting var workaround = false to var workaround = true to observe desired behavior.
How can I get exactly what is really selected?
Current workaround
I'm currently adding those objects into an array on selection and use those items instead of project.getItems({selected: true}).
The thing is that in Paper.js architecture, curves and segments are not items (they are part of a specific item which is the path). So you shouldn't expect project.getItems() to return anything else than items.
Another thing you have to know is that a path is assumed selected if any of its part is selected (curves, segments, points, handles, position, bounds, ...). And a curve is assumed selected if all of its parts are selected (points and handles).
With that in mind, you can create an algorithm to retrieve "what is really selected" based on project.getItems({selected: true}) as its first part. Then, you need to loop through curves and segments to check if they are selected.
Here is a sketch demonstrating a possible solution.
var vector = new Point(10, 10);
// Create path.
var path = new Path({
segments: [
[100, 100],
[200, 100],
[260, 170],
[360, 170],
[420, 250]
],
strokeColor: 'red',
strokeWidth: 10
});
// Translate given thing along global vector.
function translateThing(thing) {
switch (thing.getClassName()) {
case 'Path':
thing.position += vector;
break;
case 'Curve':
thing.segment1.point += vector;
thing.segment2.point += vector;
break;
case 'Segment':
thing.point += vector;
break;
}
}
// On mouse down...
function onMouseDown(event) {
// ...only select what was clicked.
path.selected = false;
hit = paper.project.hitTest(event.point);
if (hit && hit.location) {
hit.location.curve.selected = true;
}
else if (hit && hit.segment) {
hit.segment.selected = true;
}
// We check all items for demo purpose.
// Move all selected things.
// First get selected items in active layer...
project.activeLayer.getItems({ selected: true })
// ...then map them to what is really selected...
.map(getSelectedThing)
// ...then translate them.
.forEach(translateThing);
}
// This method returns what is really selected in a given item.
// Here we assume that only one thing can be selected at the same time.
// Returned thing can be either a Curve, a Segment or an Item.
function getSelectedThing(item) {
// Only check curves and segments if item is a path.
if (item.getClassName() === 'Path') {
// Check curves.
for (var i = 0, l = item.curves.length; i < l; i++) {
if (item.curves[i].selected) {
return item.curves[i];
}
}
// Check segments.
for (var i = 0, l = item.segments.length; i < l; i++) {
if (item.segments[i].selected) {
return item.segments[i];
}
}
}
// return item by default.
return item;
}
That said, depending on your real use case, your current workaround could be more appropriate than this approach.
I'm using the week view, but instead of showing 7 columns per slide I want to show three columns, is it possible to archive this?
I failed to see any related method on the official documentation: http://fullcalendar.io/docs/
Version 2.2.5+ of Full Calendar has this kind of customization built in.
You just need to do something like this:
views: {
agendaThreeDay: {
type: 'agenda',
duration: { days: 3 },
buttonText: '3 day'
},
defaultView: 'agendaThreeDay'
}
You can get more information on this from the document page here.
Pull the source, use this code (may need some additional change).
src/agenda/AgendaThreeDayView.js
fcViews.agendaThreeDay = AgendaThreeDayView;
function AgendaThreeDayView(a) {
AgendaView.call(this, a);
}
AgendaThreeDayView.prototype = createObject(AgendaView.prototype);
$.extend(AgendaThreeDayView.prototype, {
name: "agendaThreeDay",
incrementDate: function(a, b) {
return a.clone().stripTime().add(b, "days");
},
render: function(a) {
this.intervalStart = a.clone().stripTime();
this.intervalEnd = this.intervalStart.clone().add(3, "days");
this.start = this.skipHiddenDays(this.intervalStart);
this.end = this.skipHiddenDays(this.intervalEnd, -1, true);
this.title = this.calendar.formatRange(this.start, this.end.clone().subtract(1), this.opt("titleFormat"), " — ");
AgendaView.prototype.render.call(this, 3);
}
});
Edit:
Remembered that you need to add the file to lumbar.json
Look here for how to build: https://github.com/arshaw/fullcalendar/wiki/Contributing-Code
I have a choropleth(world map) and a bubble chart in dc.js. The colors in the bubbles and the map should be the same (country wise). On selection of a country, the filtered bubble should have the same color as of the map because the map and bubbles are linked with the same country.
How am i suppose to achieve it.
Any suggestion will be helpful.
Thanks in advance.
You should be able to set the same color scale for all the charts, as long as the keys (country names) are the same across charts.
EDIT: because of the limitations below, probably the best approach is to use a custom reduce function that produces an object or tuple. Something like (untested):
that.countrywiseInvGroup = that.countries.group().reduce(
function(d, p) {
p.inv += d.initial_inv;
p.country = d.country;
return p;
},
function(d, p) {
p.inv -= d.initial_inv;
return p;
},
function() {
return {inv: 0};
});
// ...
.colorAccessor(function (d) {
return d.country;
})
.title(function (d) {
if(d.value){
return "Country: " + d.key + "\nTotal Initial Investment: USD $" + that.formatCurrency(d.value.inv);
}
})
```
I am trying to create a custom reduce function for a dataset attribute group that would sum a number of unique values for another attribute.
For example, my dataset looks like a list of actions on projects by team members:
{ project:"Website Hosting", teamMember:"Sam", action:"email" },
{ project:"Website Hosting", teamMember:"Sam", action:"phoneCall" },
{ project:"Budjet", teamMember:"Joe", action:"email" },
{ project:"Website Design", teamMember:"Joe", action:"design" },
{ project:"Budget", teamMember:"Sam", action:"email" }
So, team members work on a variable number of projects by performing one action per line. I have a dimension by team member, and would like to reduce it by the number of projects (uniques).
I tried the below (storing project in a uniques array) without success (sorry, this might hurt your eyes):
var teamMemberDimension = dataset.dimension(function(d) {
return d.teamMember;
});
var teamMemberDimensionGroup = teamMemberDimension.group().reduce(
// add
function(p,v) {
if( p.projects.indexOf(v.project) == -1 ) {
p.projects.push(v.project);
p.projectsCount += 1;
}
return p;
},
// remove
function(p,v) {
if( p.projects.indexOf(v.projects) != -1 ) {
p.projects.splice(p.projects.indexOf(v.projects), 1);
p.projectsCount -= 1;
}
return p;
},
// init
function(p,v) {
return { projects:[], projectsCount:0 }
}
);
Thanks a lot!
Edit after DJ Martin's answer ::
So, to be clearer, I would like to get the numbers I am after here would be:
-----------
Sam : 2 (projects he is workin on, no matter the number of actions)
Joe : 2 (projects he is workin on, no matter the number of actions)
-----------
The answer provided by DJ Martin gets me there. But rather than hard coding a table, I would like to find a way to use these numbers for my DC.JS bar chart. When I was only using the number of actions (so just a reduceCount() ), I did it like below:
teamMemberChart.width(270)
.height(220)
.margins({top: 5, left: 10, right: 10, bottom: 20})
.dimension(teamMemberDimension)
.group(teamMemberDimensionGroup)
.colors(d3.scale.category20())
.elasticX(true)
.xAxis().ticks(4);
I guess there might be something to change in the group().
UPDATED ANSWER
Sorry I misunderstood the question... you are actually on the right track. You'll just need to maintain a count of each project so that your subtract function can know when to remove the value.
teamMemberGroup = teamMemberDimension.group().reduce(
function (p, d) {
if( d.project in p.projects)
p.projects[d.project]++;
else p.projects[d.project] = 1;
return p;
},
function (p, d) {
p.projects[d.project]--;
if(p.projects[d.project] === 0)
delete p.projects[d.project];
return p;
},
function () {
return {projects: {}};
});
Here is an updated fiddle: http://jsfiddle.net/djmartin_umich/3LyhL/