Coder Social home page Coder Social logo

Comments (13)

Lemen47Nic avatar Lemen47Nic commented on July 22, 2024 1

i made an example app for show you my problem:

package legnannic.chartsexample;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import lecho.lib.hellocharts.model.Axis;
import lecho.lib.hellocharts.model.AxisValue;
import lecho.lib.hellocharts.model.Line;
import lecho.lib.hellocharts.model.LineChartData;
import lecho.lib.hellocharts.model.PointValue;
import lecho.lib.hellocharts.model.SimpleValueFormatter;
import lecho.lib.hellocharts.view.LineChartView;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {
    private float max;
    private float min;
    private float max1;
    private float min1;

    private float range;
    private float scale;
    private float sub;

    private LineChartView chart;
    private LineChartData data;
    private Line line;
    private List<PointValue> values;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        chart = (LineChartView) findViewById(R.id.chart);

        List<Line> lines = new ArrayList<Line>();
        // ***************PRIMA LINEA***************************************
        values = new ArrayList<PointValue>();
        values.add(new PointValue(0, 0));
        values.add(new PointValue(1, 4));
        values.add(new PointValue(2, 5));
        values.add(new PointValue(3, 7));
        values.add(new PointValue(4, 9));
        values.add(new PointValue(5, 10));
        values.add(new PointValue(6, 3));
        values.add(new PointValue(7, 2));
        values.add(new PointValue(8, 11));
        values.add(new PointValue(9, 15));
        values.add(new PointValue(10, 3));
        values.add(new PointValue(11, 4));
        values.add(new PointValue(12, 5));
        values.add(new PointValue(13, 6));

        line = new Line(values).setCubic(false).setHasPoints(false)
                .setStrokeWidth(1);
        // .setHasLabels(true);

        line.setColor(Color.BLUE);
        max = 15;
        min = 0;

        lines.add(line);

        // SECOND LINE
        min1 = 0;
        max1 = 100000;
        range = max - min;

        scale = (range / (max1 - min1));// + 0.3f;
        sub = (min1 * scale) - min;// / 1.02f;

        values = new ArrayList<PointValue>();
        values.add(new PointValue(0, 0 * scale - sub));
        values.add(new PointValue(1, 44000 * scale - sub));
        values.add(new PointValue(2, 66623 * scale - sub));
        values.add(new PointValue(3, 93523 * scale - sub));
        values.add(new PointValue(4, 11345 * scale - sub));
        values.add(new PointValue(5, 15346 * scale - sub));
        values.add(new PointValue(6, 13866 * scale - sub));
        values.add(new PointValue(7, 23376 * scale - sub));
        values.add(new PointValue(8, 34543 * scale - sub));
        values.add(new PointValue(9, 32346 * scale - sub));
        values.add(new PointValue(10, 41523 * scale - sub));
        values.add(new PointValue(11, 32546 * scale - sub));
        values.add(new PointValue(12, 74580 * scale - sub));
        values.add(new PointValue(13, 100000 * scale - sub));

        line = new Line(values).setCubic(false).setHasPoints(false)
                .setStrokeWidth(1);
        // .setHasLabels(true);

        line.setColor(Color.RED);

        lines.add(line);

        data = new LineChartData(lines);

        // asseX sotto
        List<AxisValue> axisValues = new ArrayList<AxisValue>();
        float limit = values.get(values.size() - 1).getX();
        limit *= 1000;// da chilometri a metri
        for (float i = 0; i < limit; i++) {
            axisValues.add(new AxisValue(i / 1000, formatKm(i)));
        }
        Axis tempoAxis = new Axis(axisValues).setMaxLabelChars(10)
                .setHasLines(true).setLineColor(Color.BLACK)
                .setTextColor(Color.BLACK);
        data.setAxisXBottom(tempoAxis);

        data.setAxisYLeft(new Axis().setTextColor(Color.BLUE).setHasLines(true)
                .setLineColor(Color.BLACK));

        // data.setAxisYRight(new Axis()
        // .setTextColor(Color.RED)
        // .setMaxLabelChars(5)
        // .setFormatter(
        // new HeightValueFormater(scale, sub, 1, null, null)));
        axisValues = new ArrayList<AxisValue>();
        for (float i = 0; i < max1; i += 1000) {
            axisValues.add(new AxisValue(i, formatMinutes((long) i)));
        }
        tempoAxis = new Axis(axisValues)
                .setMaxLabelChars(5)
                .setTextColor(Color.RED)
                .setHasSeparationLine(false)
                .setFormatter(
                        new HeightValueFormater(scale, sub, 0, null, null));
        data.setAxisYRight(tempoAxis);

        chart.setLineChartData(data);
        // chart.setValueSelectionEnabled(true);
    }

    private char[] formatKm(float i) {
        StringBuilder sb = new StringBuilder();
        sb.append(i / 1000).append("km");
        return sb.toString().toCharArray();
    }

    private static class HeightValueFormater extends SimpleValueFormatter {
        private float scale;
        private float sub;

        public HeightValueFormater(float scale, float sub, int digits,
                char[] prependedText, char[] apendedText) {
            // Don't use auto digits for auto-generated axes, instead use digits
            // number passed in parameter.
            super(digits, true, prependedText, apendedText);
            this.scale = scale;
            this.sub = sub;
        }

        @Override
        public int formatAutoValue(char[] formattedValue, float[] values,
                int digits) {
            int index = values.length - 1;// I just need last value from this
                                            // array because
                                            // SimpleValueFormatter
            // uses only last value and that is enough for axis labels.
            values[index] = (values[index] + sub) / scale;
            return super.formatAutoValue(formattedValue, values, digits);
        }
    }

    public char[] formatMinutes(long time) {
        StringBuilder sb = new StringBuilder();

        // translate value to seconds, for example
        long second = TimeUnit.MILLISECONDS.toSeconds(time) % 60;
        long minute = TimeUnit.MILLISECONDS.toMinutes(time) % 60;
        long hour = TimeUnit.MILLISECONDS.toHours(time);

        if (hour > 0) {
            sb.append(String.valueOf(hour)).append(':');
        }
        if (minute < 10) {
            sb.append('0');
        }
        sb.append(String.valueOf(minute)).append(':');
        if (second < 10) {
            sb.append('0');
        }
        sb.append(String.valueOf(second));
        return sb.toString().toCharArray();
    }
}

in this point
tempoAxis = new Axis(axisValues)
.setMaxLabelChars(5)
.setTextColor(Color.RED)
.setHasSeparationLine(false)
.setFormatter(
new HeightValueFormater(scale, sub, 0, null, null));
data.setAxisYRight(tempoAxis);
if i remove axisValues on new Axis result is
screenshot_2015-01-13-11-43-41 1

and its alright but if i set axisValues
screenshot_2015-01-13-11-43-22 1

what i did wrong?

from hellocharts-android.

lecho avatar lecho commented on July 22, 2024

Hi,

  1. yes if you have both lines with similar min and max values. In that case you can use for example left auto-generated axis and right manual axis. But if you have lines that have huge Y values differences(for example first line Y values(0;50) and second line Y values(0;1000)) you will probably need to use some kind of scale.

  2. HeightValueFormatter is simple example, it works only for numbers and it skips scale attribute if AxisValue has string label, in your case you set formated label when you create axis values.
    Solution: if you have already formatted labels as char[] for every AxisValue you can just use default formatter for tempoAxis.

ArrayList axisValues = new ArrayList();
for (float i = 0; i < maxTime; i += 1000) {
    axisValues.add(new AxisValue(i,//here you can scale `i` value to adjust axis values if needed
        moreWorkouts.formatMinutes((long) i)));//formated label as array of chars
}
Axis tempoAxis = new Axis(axisValues)
.setMaxLabelChars(5)
.setTextColor(Color.RED)
.setHasSeparationLine(false);
//.setFormatter(new HeightValueFormater(scale, sub, 1, null, null));//probably not needed
  1. no but this is a good idea and I should be able to do that, I just need to close some other issues before I start with this.

from hellocharts-android.

Lemen47Nic avatar Lemen47Nic commented on July 22, 2024

ok thanks for answer but i dont resolve my problem, and maybe i found a bug (or i do something wrong).
i try to explain you what i try to do.
i'm realizing a runner up, like runtastic, with charts for show stats. stats shows on chart is dinamic and can be change with different button for axes x, y left and y right.
On one chart i have dates of workout like axis x and on axes y i can have max speed for workout, average speed for workout, distance or time of workout, without different for left or right. now at start i set axis x dates and axis y left as speed average. when i use button and choise axis y right like distance i haven't problem.

data.setAxisYRight(new Axis()
.setTextColor(Color.RED)
.setMaxLabelChars(5)
.setHasSeparationLine(false)
.setFormatter(
new HeightValueFormater(scale, sub, 1, null,
null)));

if i choise time like axis y left and i have/haven't axis y right it work.

ArrayList axisValues = new ArrayList();
for (float i = 0; i < maxTime; i += 1000) {
axisValues.add(new AxisValue(i, moreWorkouts
.formatMinutes((long) i)));
}
Axis tempoAxis = new Axis(axisValues).setHasLines(true)
.setMaxLabelChars(5).setLineColor(Color.BLACK)
.setTextColor(Color.BLUE).setHasSeparationLine(false);

    data.setAxisYLeft(tempoAxis);

axis y right with code below.

then if i have speed on left and choise time on right, axis show only 00:00 at bottom-right and no other value. it's the same within or without height value formater. i tried to modify value of "i" but without results.

i have two different time really and if i choise one on left and one on right, at right i can show the char value created but not scaled.

maybe i do something wrong.

another thing, that i think it'sa bug, it's that. for example:
if i choise first on left speed and on right time and than i switch this selection, application crash.
the same if i choise first time on left and speed on righet and then i switch.
difference between time and speed it's only that in speed the value is autogenerated and in time it's passed on constructor of Axis.

01-12 11:52:12.752: E/AndroidRuntime(21718): FATAL EXCEPTION: main
01-12 11:52:12.752: E/AndroidRuntime(21718): Process: cmd.run.main, PID: 21718
01-12 11:52:12.752: E/AndroidRuntime(21718): java.lang.ArrayIndexOutOfBoundsException: length=13; index=13
01-12 11:52:12.752: E/AndroidRuntime(21718): at lecho.lib.hellocharts.renderer.AxesRenderer.prepareAxisVerticalAuto(AxesRenderer.java:600)
01-12 11:52:12.752: E/AndroidRuntime(21718): at lecho.lib.hellocharts.renderer.AxesRenderer.prepareAxis(AxesRenderer.java:337)
01-12 11:52:12.752: E/AndroidRuntime(21718): at lecho.lib.hellocharts.renderer.AxesRenderer.drawInBackground(AxesRenderer.java:135)
01-12 11:52:12.752: E/AndroidRuntime(21718): at lecho.lib.hellocharts.view.AbstractChartView.onDraw(AbstractChartView.java:87)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.draw(View.java:15303)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14197)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14239)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3272)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14134)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14239)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3272)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14134)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14239)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3272)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14134)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14239)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3272)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14134)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14239)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3272)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14134)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14239)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3272)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14134)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14239)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3272)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14134)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.View.getDisplayList(View.java:14239)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1570)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1449)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2705)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2571)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2143)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1236)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6471)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.Choreographer.doCallbacks(Choreographer.java:603)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.Choreographer.doFrame(Choreographer.java:573)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.os.Handler.handleCallback(Handler.java:733)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.os.Handler.dispatchMessage(Handler.java:95)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.os.Looper.loop(Looper.java:157)
01-12 11:52:12.752: E/AndroidRuntime(21718): at android.app.ActivityThread.main(ActivityThread.java:5356)
01-12 11:52:12.752: E/AndroidRuntime(21718): at java.lang.reflect.Method.invokeNative(Native Method)
01-12 11:52:12.752: E/AndroidRuntime(21718): at java.lang.reflect.Method.invoke(Method.java:515)
01-12 11:52:12.752: E/AndroidRuntime(21718): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
01-12 11:52:12.752: E/AndroidRuntime(21718): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
01-12 11:52:12.752: E/AndroidRuntime(21718): at dalvik.system.NativeStart.main(Native Method)

from hellocharts-android.

Lemen47Nic avatar Lemen47Nic commented on July 22, 2024

if i switch left and right it work
screenshot_2015-01-13-11-59-41 1

and if i use two times format no with scale
screenshot_2015-01-13-12-03-29 1

from hellocharts-android.

Lemen47Nic avatar Lemen47Nic commented on July 22, 2024

i saw that with values on new axis than this code

@OverRide
public int formatAutoValue(char[] formattedValue, float[] values,
int digits) {
int index = values.length - 1;// I just need last value from this
// array because
// SimpleValueFormatter
// uses only last value and that is enough for axis labels.
values[index] = (values[index] + sub) / scale;
return super.formatAutoValue(formattedValue, values, digits);

dont work

from hellocharts-android.

Lemen47Nic avatar Lemen47Nic commented on July 22, 2024

I tried to create the error I mentioned above whit this example app, what i think is bug, but without result

from hellocharts-android.

lecho avatar lecho commented on July 22, 2024

I tired your code, looks like the problem is in the loop when you create AxisValues for right Y axis. Axis value(first parameter in AxisValue(flaot, char[]) constructor) should be scaled to be within Y ranges of chart, the same way that you scale Y values for second line. Try the following code:

 axisValues = new ArrayList<AxisValue>();
        for (float i = 0; i < max1; i += 1000) {
            axisValues.add(new AxisValue(i * scale - sub, formatMinutes((long) i)));//important i * scale - sub
}
rightAxis= new Axis(axisValues).setMaxLabelChars(5).setTextColor(Color.RED).setHasSeparationLine(false)
                .setFormatter(new HeightValueFormater(scale, sub, 0, null, null));
data.setAxisYRight(rightAxis);

I'm still not sure what caused exception you pasted. Maybe you have modified chart's data and not called setLineChartData again, in that case chart will reference to new data but some internal structures will not be recalculated. I have plans to make chart data immutable in the future to prevent that kind of situations.

btw. this month I've pushed new implementations of value formatters so you can update your copy of this repository.

from hellocharts-android.

Lemen47Nic avatar Lemen47Nic commented on July 22, 2024

ok thanks now it's scaled, thank you.
but the "bug" still. i would like to send you a video to show you, how can i?

from hellocharts-android.

lecho avatar lecho commented on July 22, 2024

I think you can send me link to video(shared via dropbox or other site) in a email [email protected] or create a GIF and post it here.

from hellocharts-android.

Lemen47Nic avatar Lemen47Nic commented on July 22, 2024

hi, i sent an email to you sometime ago but i never received an answer.

from hellocharts-android.

lecho avatar lecho commented on July 22, 2024

Hi, sorry for late reply, I missed your mail because it was mark as a spam, probably because of binaries in attachment.
I think I've just fixed this issue in commit 51784b8
I've send you back project with hellocharts-library-1.5.1.jar

from hellocharts-android.

Lemen47Nic avatar Lemen47Nic commented on July 22, 2024

goodmorning,
thanks a lot!! now it work great!! thank you!!

Date: Tue, 3 Mar 2015 13:36:40 -0800
From: [email protected]
To: [email protected]
CC: [email protected]
Subject: Re: [hellocharts-android] help with multiple lines (#48)

Hi, sorry for late reply, I missed your mail because it was mark as a spam, probably because of binaries in attachment.

I think I've just fixed this issue in commit 51784b8


Reply to this email directly or view it on GitHub.

from hellocharts-android.

Ankita-Goyal avatar Ankita-Goyal commented on July 22, 2024

Please tell, what will be the output of this one-
List list=new ArrayList<>(2);//Line 1
listadd("Red");//Line2
listadd(new Color());//Line3

from hellocharts-android.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.